這篇文章主要介紹了java 中線程等待與通知的實現的相關資料,希望透過本文能幫助到大家,讓大家掌握這樣的功能,需要的朋友可以參考下
#java 中執行緒等待與通知的實作
前言:
關於等待/通知,要記住的關鍵點是:
必須從同步環境內呼叫wait()、notify()、notifyAll()方法。執行緒不能呼叫物件上等待或通知的方法,除非它擁有那個物件的鎖。
wait()、notify()、notifyAll()都是Object的實例方法。與每個物件具有鎖一樣,每個物件可以有一個執行緒列表,他們等待來自該訊號(通知)。執行緒透過執行物件上的wait()方法來獲得這個等待清單。從那時候起,它不再執行任何其他指令,直到呼叫物件的notify()方法。如果多個執行緒在同一個物件上等待,則將只選擇一個執行緒(不保證以何種順序)繼續執行。如果沒有線程等待,則不採取任何特殊操作。
範例程式碼:
package threadwait; public class ThreadA extends Thread{ public int num = 0; public void run(){ synchronized (this){//在此类对象上实现同步,this指代当前对象 for(int i = 0 ; i < 3 ; ++i) this.num+=i; notifyAll();//通知所有在这个对象上等待的线程开始执行,在这里就是通知TestNotify主线程开始执行 } } public int getNum(){ return this.num; } }
package threadwait; public class TestNotify{ public static void main(String args[]){ ThreadA threada = new ThreadA(); threada.start();//threada线程有执行的资格,但是还没有开始执行 synchronized(threada){ try{ threada.wait();//主线程等待threada线程执行结束才开始执行 //而且只有获得了当前threada对象的锁之后才能执行wait,就是说在同步域内才可以执行wait,执行wait后放弃对象锁 }catch(InterruptedException e){ e.printStackTrace(); } } System.out.println(threada.getNum()); } }
同步可以是在class層級上的,synchronized(A.class) ,也可以是在物件層級上的synchronized(this),可以是靜態同步方法,static synchronized ,靜態同步方法是在class層級上的,非靜態同步方法是在類別物件層級上的,一個類別物件只有一個鎖,只有獲得了該鎖才可以對他執行wait操作,後釋放掉該鎖。
更進一步的實例程式碼如下:
package threadwait; public class ThreadA extends Thread{ public int num = 0; public void run(){ synchronized (this){//在此类对象上实现同步,this指代当前对象 for(int i = 0 ; i < 3 ; ++i) this.num+=i; try{ Thread.sleep(500);//如果ThreadB的三个示例线程在还没有进入等待状态之前就受到了notifyall的信号 //那将会发生严重后果,因为调用notifyall的线程只可以调用一次notifyall,那造成等待的线程将永远等待下去 //所以在此处让它睡一小会,让其他线程有时间进入等待状态。 //不然会收到 }catch(InterruptedException e){ e.printStackTrace(); } notifyAll();//通知所有在这个对象上等待的线程开始执行,在这里就是通知TestNotify主线程开始执行 } // notifyAll(); } public int getNum(){ return this.num; } }
package threadwait; public class ThreadB extends Thread{ private ThreadA threada; public ThreadB(ThreadA ta){ this.threada = ta; } public void run(){ System.out.println(Thread.currentThread().getName()+" is waitting."); synchronized(threada){ try{ threada.wait(); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" "+this.threada.getNum()); } } }
package threadwait; public class TestNotify{ public static void main(String args[]){ ThreadA threada = new ThreadA(); new ThreadB(threada).start(); new ThreadB(threada).start(); new ThreadB(threada).start(); threada.start(); } }
以上是Java中執行緒等待與通知的實作方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!