java多线程

 

 

一:买票的案例:通过Thread  和Runale实现多线程

//通过Thread实现
package mypack;

class Ticket extends Thread{
    
    private static int ticket=100;
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            if(ticket>0){
                System.out.println(Thread.currentThread().getName()+"...sale..."+ticket--);
            }else{
                break;
            }
        }
    }
}

public class TicketDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Ticket t1 = new Ticket();
        Ticket t2 = new Ticket();
        t1.start();
        t2.start();
    }

}

//通过继承Runnable实现
package mypack;

class Ticket implements Runnable{
    private int ticket = 100;
    
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            if(ticket>0){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"...sale..."+ticket--);
            }else{
                break;
            }
            
        }
    }
    
}

public class TicketDemo2 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Ticket t = new Ticket();
        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        t1.start();
        t2.start();
    }
}

//上面两种方法功能一样,不过Thread


 

二:多线程异常

package mypack;

class Ticket extends Thread{
	
	private static int ticket=100;
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			if(ticket>0){
				try {
					Thread.sleep(100); //睡眠,转让执行权
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"...sale..."+ticket--);
			}else{
				break;
			}
		}
	}
}

public class TicketDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Ticket t1 = new Ticket();
		Ticket t2 = new Ticket();
		t1.start();
		t2.start();
	}

}
//上面就是让线程睡眠,然后在苏醒时候,别的进程已经改变了原变量的内容

  多线程运行安全问题:
  问题原因:
  当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没执行完,另一个线程参与进来执行,导致共享数据的错误.
  解决办法;对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行.

解决多线程问题

synchronize(对象){

}

  

通过同步代码块解决线程安全问题


解决多线程问题:
1,明确那些代码是多线程运行代码.
2,明确共享数据.
3,明确多线程运行代码中那些语句是操作共享数据.



package
mypack; class Ticket extends Thread { Object obj = new Object();//创建上帝对象 private static int ticket = 100; public void run() { // TODO Auto-generated method stub while (true) { synchronized (obj) { if (ticket > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "...sale..." + ticket--); } else { break; } } } } } public class TicketDemo { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Ticket t1 = new Ticket(); Ticket t2 = new Ticket(); t1.start(); t2.start(); } }

 通过同步函数解决安全问题

package mypack;

class Bank {
	private int sum;
	Object obj = new Object();
	// 同步函数
	public synchronized void add(int n) { 
		sum = sum + n;
		System.out.println("sum = " + sum);

	}
}

class Cus implements Runnable {

	private Bank b = new Bank();

	public void run() {
		// TODO Auto-generated method stub

		for (int i = 0; i < 3; i++) {
			b.add(100);

		}
	}

}

public class BankDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Cus c = new Cus();
		Thread t1 = new Thread(c);
		Thread t2 = new Thread(c);
		t1.start();  //每个线程和每个线程的run方法是分开的,run方法是独立运行的,
		t2.start();
	}

}

同步函数用的锁是那一个?
函数需要被对象调用,那么函数都有一个所属对象引用,就是this.
所以同步函数使用的锁是shis.

 

同步函数和同步代码块共同操作共享数据

package mypack;

class Ticket implements Runnable {
	private int ticket = 100;
	Object obj = new Object();
	boolean flag = true;

	public void run() {
		// TODO Auto-generated method stub
		if (flag) {
			while (true) {
				synchronized (this) {	//这里要确保操作共享数据使用的synchronized 对象是一样
					if (ticket > 0) {
						try {
							Thread.sleep(10);
						} catch (InterruptedException e) {
						}
						System.out.println(Thread.currentThread().getName()
								+ "...code..." + ticket--);
					} else {
						return;
					}
				}
			}
		} else {
			while (true) {
				show();
			}
		}
	}

	public synchronized void show() {
		if (ticket > 0) {
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
			}
			System.out.println(Thread.currentThread().getName() + "...show..."
					+ ticket--);
		} else {
			return;
		}
	}

}

public class TicketDemo2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Ticket t = new Ticket();
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		t1.start();
		//当启动main函数时候,相当于有3个线程,t1,t2,main t1.start()时候 可能拥有执行权但是还没有执行,一闪而过,t.flag=false执行完了,
		//所以要睡眠一下
		try{Thread.sleep(10);}catch(Exception e){};	
		t.flag = false;
		t2.start();
		
	}
}

  

静态同步函数的锁是Class

package mypack;

/**
 * 静态进内存,内存中没有本类对象,但是一定有该类对相应的字节码文件对象
 * 类名.class   该对象的类型是class
 * 
 * 静态的同步方法,使用的锁是该方法所在类的字节码文件对象. 类名.class
 */
class Ticket implements Runnable {
	//由于静态synchronized里面调用ticket,所以ticket要设置成静态
	private static int ticket = 100;
	Object obj = new Object();
	boolean flag = true;

	public void run() {
		// TODO Auto-generated method stub
		if (flag) {
			while (true) {
				synchronized (Ticket.class) {	//这里要确保操作共享数据使用的synchronized 对象是一样
					if (ticket > 0) {
						try {
							Thread.sleep(10);
						} catch (InterruptedException e) {
						}
						System.out.println(Thread.currentThread().getName()
								+ "...code..." + ticket--);
					} else {
						return;
					}
				}
			}
		} else {
			while (true) {
				show();
			}
		}
	}

	public static synchronized void show() {
		if (ticket > 0) {
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
			}
			System.out.println(Thread.currentThread().getName() + "...show..."
					+ ticket--);
		} else {
			return;
		}
	}

}

public class TicketDemo2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Ticket t = new Ticket();
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		t1.start();
		//当启动main函数时候,相当于有3个线程,t1,t2,main t1.start()时候 可能拥有执行权但是还没有执行,一闪而过,t.flag=false执行完了,
		//所以要睡眠一下
		try{Thread.sleep(10);}catch(Exception e){};	
		t.flag = false;
		t2.start();
		
	}
}

  

懒汉式上锁的应用

class lanhanshi{
	private lanhanshi(){}
	private static lanhanshi instance;
	//如果锁放在这里的话,每次都要去判断,比较低效
	public static synchronized lanhanshi getSingleInstance(){
		if(instance == null){	//如果在多线程中这里可能线程挂住,A挂住,B进来把下面执行,A又执行
								//要保证对象的唯一性,加锁.
			instance = new lanhanshi();
		}
		
		return instance;
	}
}

class ehanshi{
	//注意这里要用final修饰,变成常量,不可修改,
	private static final ehanshi instance = new ehanshi();
	
	private ehanshi(){}
	public ehanshi getSingleInstance(){
		return instance;
	}
}

 

优化懒汉式锁

class lanhanshi {
	private lanhanshi() {
	}

	private static lanhanshi instance;

	// 如果锁放在这里的话,每次都要去判断,比较低效
	public static lanhanshi getSingleInstance() {
		if (instance == null) {
			synchronized (lanhanshi.class) {
				if (instance == null) { // 如果在多线程中这里可能线程挂住,A挂住,B进来把下面执行,A又执行
										// 要保证对象的唯一性,加锁.
					instance = new lanhanshi();
				}
			}
		}
		return instance;
	}
}

  

懒汉式和饿汉式的差别,懒汉式是延迟加载,懒汉式有问题吗? 有.多线程访问时会出现安全问题,可以加同步,用同步代码块,和同步函数都可以,有些低效,用双重判断可以解决效率问题

 

package mypack;

class Tick implements Runnable {

	int ticket = 100;

	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			if (ticket > 0) {
				System.out.println(Thread.currentThread().getName() + "...A..."
						+ ticket--);
			}
		}
	}
}

public class Test2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//这2个tick操作的是不同的对象,ticket 不是共享
		Tick tick1 = new Tick();
		Tick tick2 = new Tick();
		Thread t1 = new Thread(tick1);
		Thread t2 = new Thread(tick2);
		t1.start();
		t2.start();
	}
}

 

写一个死锁程序

package mypack;

class Test implements Runnable{
	private boolean flag;
	Test(boolean flag){
		this.flag = flag;
	}
	
	
	public void run() {
		// TODO Auto-generated method stub
		if(flag){
			synchronized (MyLock.locka) {
				System.out.println("if locka");
				synchronized (MyLock.lockb) {
					System.out.println("if lockb");
				}
			}
		}else{
			synchronized (MyLock.lockb) {
				System.out.println("else lockb");
				synchronized (MyLock.locka) {
					System.out.println("else locka");
				}
			}
		}
	}
	
}

//线程运行时候用的锁
class MyLock{
	static Object locka = new Object();
	static Object lockb = new Object();
}

public class DeadLockDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Test test1 = new Test(true);
		Test test2 = new Test(false);
		Thread t1 = new Thread(test1);
		Thread t2 = new Thread(test2);
		t1.start();
		t2.start();
	}

}

  

解决多线程安全问题事例

package pack;

/** 
 * @Description TODO
 * @author WiKi
 * @date 2014-11-30 上午8:20:38
 */
class Input implements Runnable {
	Res r;

	Input(Res r) {
		this.r = r;
	}

	public void run() {
		// TODO Auto-generated method stub
		int x = 0;
		while (true) {
			synchronized (r) {
				if (x == 0) {
					r.name = "男人";
					r.sex = "boy";
				} else {
					r.name = "女人";
					r.sex = "girl";
				}
				x = (x + 1) % 2;
			}
		}

	}

}

class Output implements Runnable {
	Res r;

	Output(Res r) {
		this.r = r;
	}

	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			synchronized (r) {
				System.out.println(r.name + "::" + r.sex);
			}
		}
	}

}

class Res {
	String name;
	String sex;
}

public class Demo {

	public static void main(String[] args) {
		Res r = new Res();
		Input input = new Input(r);
		Output output = new Output(r);
		Thread t1 = new Thread(input);
		Thread t2 = new Thread(output);
		t1.start();
		t2.start();
	}

}

  

等待唤醒机制

只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒.

package pack;

/** 
 * @Description TODO
 * @author WiKi
 * @date 2014-11-30 上午8:20:38
 */
class Input implements Runnable {
	Res r;

	Input(Res r) {
		this.r = r;
	}

	public void run() {
		// TODO Auto-generated method stub
		int x = 0;
		while (true) {
			synchronized (r) {
				if(r.flag)
					try {
						r.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				if (x == 0) {
					r.name = "男人";
					r.sex = "boy";
				} else {
					r.name = "女人";
					r.sex = "girl";
				}
				x = (x + 1) % 2;
				r.flag = true;
				r.notify();
			}
		}

	}

}

class Output implements Runnable {
	Res r;

	Output(Res r) {
		this.r = r;
	}

	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			synchronized (r) {
				if(!r.flag)
					try {
						r.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				System.out.println(r.name + "::" + r.sex);
				r.flag = false;
				r.notify();
			}
		}
	}

}

class Res {
	String name;
	String sex;
	boolean flag;
}

public class Demo {

	public static void main(String[] args) {
		Res r = new Res();
		Input input = new Input(r);
		Output output = new Output(r);
		Thread t1 = new Thread(input);
		Thread t2 = new Thread(output);
		t1.start();
		t2.start();
	}

}

  

只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒.

等待唤醒机制代码优化

package pack;

/**
 * @Description TODO
 * @author WiKi
 * @date 2014-11-30 上午8:20:38
 */
class Input implements Runnable {
	Res r;

	Input(Res r) {
		this.r = r;
	}

	public void run() {
		// TODO Auto-generated method stub
		int x = 0;
		while (true) {
			if (x == 0) {
				r.set("男人", "man");
			} else {
				r.set("女人", "girl");
			}
			x = (x + 1) % 2;
		}

	}

}

class Output implements Runnable {
	Res r;

	Output(Res r) {
		this.r = r;
	}

	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			r.get();
		}
	}

}

class Res {
	String name;
	String sex;
	boolean flag;

	public synchronized void set(String name, String sex) {
		if (flag)
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		this.name = name;
		this.sex = sex;
		flag = true;
		this.notify();

	}

	public synchronized void get() {
		if (!flag)
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		System.out.println(name + "::" + sex);
		flag = false;
		this.notify();
	}
}

public class Demo {

	public static void main(String[] args) {
		Res r = new Res();
		Input input = new Input(r);
		Output output = new Output(r);
		Thread t1 = new Thread(input);
		Thread t2 = new Thread(output);
		t1.start();
		t2.start();
	}

}

  

notifyAll     while修饰

package pack;

class Resource{
    private String name;
    private int count = 1;
    private boolean flag = false;
    
    public synchronized void set(String name){
        if(flag)        //加了while会造成程序死掉
            try{this.wait();}catch(Exception e){};
        
        this.name = name+count++;
        System.out.println(Thread.currentThread().getName()+"...生产者"+this.name);
        flag = true;
        this.notifyAll();    //普通的notify可能唤醒本方线程,没唤醒对方线程.唤醒了本方while修饰的直接死掉
    }
    
    public synchronized void out(){
        if(!flag)
            try{this.wait();}catch(Exception e){};
        
        System.out.println(Thread.currentThread().getName()+"...消费者..."+name);
        flag = false;
        this.notifyAll();
    }
}

class Producer implements Runnable{
    Resource res;
    Producer(Resource res){
        this.res = res;
    }
    
    public void run() {
        // TODO Auto-generated method stub
        while(true)
            res.set("+商品+");
    }
    
}

class Consumer implements Runnable{
    Resource res;
    Consumer(Resource res){
        this.res = res;
    }
    
    public void run() {
        // TODO Auto-generated method stub
        while(true)
            res.out();
    }
    
}

public class Demo {

    public static void main(String[] args) {
        Resource res = new Resource();
        Producer p = new Producer(res);
        Consumer c = new Consumer(res);
        
        Thread t1 = new Thread(p);
        Thread t2 = new Thread(p);
        Thread t3 = new Thread(c);
        Thread t4 = new Thread(c);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        
    }

}

 

lock新特性替换上面方法

package pack;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Resource {
	private String name;
	private int count = 1;
	private boolean flag = false;
	Lock lock = new ReentrantLock();
	Condition condition = lock.newCondition();

	public void set(String name) {
		lock.lock();
		try {
			while (flag) // 加了while会造成程序死掉
				condition.await();
			this.name = name + count++;
			System.out.println(Thread.currentThread().getName() + "...生产者"
					+ this.name);
			flag = true;
			condition.signalAll();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public void out() {
		lock.lock();
		try {
			while (!flag)
				condition.await();
			System.out.println(Thread.currentThread().getName() + "...消费者..."
					+ name);
			flag = false;
			condition.signalAll();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
}

class Producer implements Runnable {
	Resource res;

	Producer(Resource res) {
		this.res = res;
	}

	public void run() {
		// TODO Auto-generated method stub
		while (true)
			res.set("+商品+");
	}

}

class Consumer implements Runnable {
	Resource res;

	Consumer(Resource res) {
		this.res = res;
	}

	public void run() {
		// TODO Auto-generated method stub
		while (true)
			res.out();
	}

}

public class Demo {

	public static void main(String[] args) {
		Resource res = new Resource();
		Producer p = new Producer(res);
		Consumer c = new Consumer(res);

		Thread t1 = new Thread(p);
		Thread t2 = new Thread(p);
		Thread t3 = new Thread(c);
		Thread t4 = new Thread(c);
		t1.start();
		t2.start();
		t3.start();
		t4.start();

	}

}

 

lock锁的优化 生产者消费者,线程间通信

package pack;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 这个flag判断语句依然要设置成while判断
 * 如果设置成if   t1  t2 线程是生产者  t3 t4 线程是消费者 
 * 	t1 t2 失去执行权  t3执行,然后producer_con.signal();  这时t4 获取线程运行权,但是flag是false,t4睡眠
 *  t1  t2 由于一开始就执行过  不需要判断if语句,直接执行,,这时候   就会造成 生产2次
 * @Description TODO
 * @author WiKi
 * @date 2014-11-30 下午2:07:41
 */

class Resource {
	private String name;
	private int count = 1;
	private boolean flag = false;
	Lock lock = new ReentrantLock();
	Condition producer_con = lock.newCondition();
	Condition consumer_con = lock.newCondition();
	

	public void set(String name) throws InterruptedException  {
		lock.lock();
		try {
			while (flag) // 加了while会造成程序死掉
				producer_con.await();
			this.name = name + count++;
			System.out.println(Thread.currentThread().getName() + "...生产者"
					+ this.name);
			flag = true;
			consumer_con.signal();
		}  finally {
			lock.unlock();
		}
	}

	public void out() throws InterruptedException {
		lock.lock();
		try {
			while (!flag)
				consumer_con.await();
			System.out.println(Thread.currentThread().getName() + "...消费者..."
					+ name);
			flag = false;
			producer_con.signal();
		} finally {
			lock.unlock();
		}
	}
}

class Producer implements Runnable {
	Resource res;

	Producer(Resource res) {
		this.res = res;
	}

	public void run() {
		// TODO Auto-generated method stub
		while (true)
			try {
				res.set("+商品+");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}

}

class Consumer implements Runnable {
	Resource res;

	Consumer(Resource res) {
		this.res = res;
	}

	public void run() {
		// TODO Auto-generated method stub
		while (true)
			try {
				res.out();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}

}

public class Demo {

	public static void main(String[] args) {
		Resource res = new Resource();
		Producer p = new Producer(res);
		Consumer c = new Consumer(res);

		Thread t1 = new Thread(p);
		Thread t2 = new Thread(p);
		Thread t3 = new Thread(c);
		Thread t4 = new Thread(c);
		t1.start();
		t2.start();
		t3.start();
		t4.start();

	}

}

  

多线程控制线程循环:就是控制while()的标记

package pack;

/**
 * 控制线程循环
 */

class StopThread implements Runnable{
	private boolean flag = true;
	public void run() {
		// TODO Auto-generated method stub
		while(flag){
			System.out.println("wiki");
		}
	}
	
	public void changeflag(){
		flag = !flag;
	}
	
}

public class Demo{
	public static void main(String[] args) {
		StopThread st = new StopThread();
		Thread t1 = new Thread(st);
		Thread t2 = new Thread(st);
		t1.start();
		t2.start();
		
		int count = 0;
		while(true){
			if(count++ == 60){
				st.changeflag();
				break;
			}
			System.out.println(Thread.currentThread().getName()+"::"+count);
			
		}
		
	}
}

  

停止冻结状态的线程

wait notify notifyAll 这些只能存在于synchronized 代码块里面,如果出现在其他地方会报 IllegalMonitorStateException 异常

如何停止线程?
只有一种,run方法结束.
开启多线程运行,运行代码通常是循环结构.
只要控制住循环,就可以让run方法结束,也就是线程结束.

特殊情况:
当线程处于了冻结状态, wait状态,
就不会读取到标记,那么线程就不会结束.

interrupt 中断线程. 将处于冻结状态的线程,强制恢复到运行状态,

当没有指定的方式让冻结的线程恢复到运行状态,这时需要对冻结进行清除.
强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束.

package pack;

/**
 * 控制线程循环
 */

class StopThread implements Runnable{
	private boolean flag = true;
	public void run() {
		// TODO Auto-generated method stub
		while(flag){
			try {
				System.out.println("11111111");
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				System.out.println(Thread.currentThread().getName()+"....Exception");
			}
			
			System.out.println(Thread.currentThread().getName()+"...run");
		}
	}
	
	public void changeflag(){
		flag = false;
	}
	
}

public class Demo{
	public static void main(String[] args) {
		StopThread st = new StopThread();
		Thread t1 = new Thread(st);
		Thread t2 = new Thread(st);
		t1.start();
		t2.start();
		
		int count = 0;
		while(true){
			if(count++ == 60){
				st.changeflag();
				t1.interrupt();
				t2.interrupt();
				break;
			}
			System.out.println(Thread.currentThread().getName()+"::"+count);
			
		}
		System.out.println("over");
		
	}
}

  

后台线程:,处于后台运行,任务是为其他线程提供服务

。也称为“守护线程”或“精灵线程”。JVM的垃圾回收就是典型的后台线程。

特点:若所有的前台线程都死亡,后台线程自动死亡。

设置后台线程:Thread对象setDaemon(true);

setDaemon(true)必须在start()调用前。否则出现IllegalThreadStateException异常;

前台线程创建的线程默认是前台线程;

判断是否是后台线程:使用Thread对象的isDaemon()方法;

并且当且仅当创建线程是后台线程时,新线程才是后台线程。

 

创建一个后台线程

package pack;

class Ticket implements Runnable{

	public void run() {
		// TODO Auto-generated method stub
		while(true){
			System.out.println(Thread.currentThread().getName());
		}
	}
	
}

public class Demo {

	public static void main(String[] args) {
		Ticket ticket = new Ticket();
		Thread t1 = new Thread(ticket);
		Thread t2 = new Thread(ticket);
		System.out.println("main thread");
		
		t1.setDaemon(true);
		t1.start();
		t2.start(); //如果t2不运行的话,t1会运行几次,发现main线程 结束了,他也就结束了,不过有个时间间隔
			//t2运行的话,  t1和t2会交互执行
	}
}

 

join 等待线程结束/死亡

package pack;

class JoinDemo implements Runnable {

	public void run() {
		// TODO Auto-generated method stub
		for (int i = 0; i < 70; i++) {
			System.out.println(Thread.currentThread().getName() + "...." + i);
		}
	}

}

public class Demo {
	public static void main(String[] args) throws InterruptedException {
		JoinDemo jd = new JoinDemo();
		Thread t1 = new Thread(jd);
		Thread t2 = new Thread(jd);
		t1.start();
//		t1.join();	当join放在这里,当执行到这里,main释放执行权,然后让t1线程死掉,main才恢复,才会继续执行后面
		t2.start();
//		t1.join();  当join放这里,执行到这里,main释放执行权,t1,t2,2线程抢执行权,只有在t1执行完,main才恢复执行
					//这是如果t2还没执行完,  main和t2抢执行权

		for (int i = 0; i < 60; i++) {
			System.out.println(Thread.currentThread().getName() + "...main..."
					+ "..." + i);
		}
		System.out.println("over");
	}
}

  

线程的优先级

static int MAX_PRIORITY 线程可以具有的最高优先级。 10
static int MIN_PRIORITY 线程可以具有的最低优先级。 1
static int NORM_PRIORITY 分配给线程的默认优先级。 5
//t1.setPriority(Thread.MIN_PRIORITY);

yield用法:yield 暂停当前正在执行的线程对象,并执行其他线程。这个只是稍微减缓线程运行,可能那个线程还是自身

package pack;

class Ticket implements Runnable{

	public void run() {
		// TODO Auto-generated method stub
		for(int i=0;i<30;i++){
			System.out.println(Thread.currentThread().toString());
			Thread.yield();
		}
	}
}

public class Demo {
	public static void main(String[] args) throws InterruptedException {
		Ticket ticket = new Ticket();
		Thread t1 = new Thread(ticket);
		Thread t2 = new Thread(ticket);
//		t1.setPriority(Thread.MIN_PRIORITY);
		t1.start();
		t2.start();
		
		
		System.out.println("over");
	}
}

  

 多线程的运用

package pack;

public class Demo {
	public static void main(String[] args) {

		new Thread() {
			public void run() {
				for (int i = 0; i < 30; i++) {
					System.out.println(Thread.currentThread().getName() + "..."
							+ i);
				}
			};
		}.start();

		Runnable r = new Runnable() {
			public void run() {
				for (int i = 0; i < 30; i++) {
					System.out.println(Thread.currentThread().getName() + "..."
							+ i);
				}

			}
		};

		new Thread(r).start();

		for (int i = 0; i < 30; i++) {
			System.out.println(Thread.currentThread().getName() + "..." + i);
		}
	}
}

  

posted @ 2014-11-28 10:02  wikiki  阅读(237)  评论(0编辑  收藏  举报