多執行緒中的wait()和notify()方法
阿新 • • 發佈:2019-01-27
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);//將執行緒暫停