1. 程式人生 > >多執行緒中的wait()和notify()方法

多執行緒中的wait()和notify()方法

wait()和notify()方法屬於Object類中的方法,是用於對執行緒之間進行資源物件鎖的通訊,其必須在synchronized(Obj){...}語法塊內

wait()就是說執行緒在獲取物件鎖後,主動釋放物件鎖,同時本執行緒進行休眠。直到有其它執行緒呼叫該物件的notify()喚醒該執行緒,才能繼續獲取物件鎖,並繼續執行

notify()就是對物件鎖的喚醒操作。但有一點需要注意的是notify()呼叫後,並不是馬上就釋放物件鎖的,而是在相應的synchronized(){}語句塊執行結束,自動釋放鎖後,JVM會在wait()物件鎖的執行緒中隨機選取一執行緒,賦予其物件鎖,喚醒執行緒,繼續執行

eg1.一個很經典的面試題,用執行緒鎖實現印表機列印ABCABCABCABCABC

package com.lmr.thread;

//執行緒加鎖

public class TestSynchronized {

	public static void main(String[] args) throws InterruptedException {
		
		Object a = new Object();   
        Object b = new Object();   
        Object c = new Object();   
		
		Thread thread1=new Thread(new MyThreadPrint("A",c,a));
		Thread thread2=new Thread(new MyThreadPrint("B",a,b));
		Thread thread3=new Thread(new MyThreadPrint("C",b,c));
		
		thread1.start();
		Thread.sleep(100);
		thread2.start();
		Thread.sleep(100);
		thread3.start();
		Thread.sleep(100);
		
	}
	
}

class MyThreadPrint implements Runnable{

	private String name;
	private Object prev;
	private Object self;
	
	public MyThreadPrint(String name, Object prev, Object self){
		
		this.name=name;
		this.prev=prev;
		this.self=self;
		
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		int count=5;
		
		while(count>0){
			
			synchronized (prev) {
				synchronized (self) {
				
					System.out.println("   "+count+"  "+name);
					count--;
					self.notify();
					
				}
				try {
					prev.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
   5  A
   5  B
   5  C
   4  A
   4  B
   4  C
   3  A
   3  B
   3  C
   2  A
   2  B
   2  C
   1  A
   1  B
   1  C
eg2.利用wait()和notify()實現執行緒的暫停和繼續
package com.lmr.thread;

public class Runnable_1 extends Thread implements Runnable{

	private int num=0;
	
	private Boolean flag = false;
	private Object lock=new Object();
	
	public Boolean getFlag() {
		return flag;
	}

	public void setFlag(Boolean flag) {
		
		if(flag){
			synchronized (lock) {
				lock.notify();
			}
		}
		
		this.flag = flag;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		while(true){
			
			synchronized (lock) {
			
				if(!flag){
					try {
						lock.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
				System.out.println(num++);
				
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
			
		}
		
	}

}
對應的使用方式
thread1=new Runnable_1();
thread1.start();
thread1.setFlag(true);//將執行緒繼續
thread1.setFlag(false);//將執行緒暫停