wait和notify的理解与使用
1.對(duì)于wait()和notify()的理解
對(duì)于wait()和notify()的理解,還是要從jdk官方文檔中開始,在Object類方法中有:
void notify()?
Wakes up a single thread that is waiting on this object’s monitor.?
譯:喚醒在此對(duì)象監(jiān)視器上等待的單個(gè)線程
void notifyAll()?
Wakes up all threads that are waiting on this object’s monitor.?
譯:喚醒在此對(duì)象監(jiān)視器上等待的所有線程
void wait( )?
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll( ) method for this object.?
譯:導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對(duì)象的notify( ) 方法或 notifyAll( ) 方法
void wait(long timeout)?
Causes the current thread to wait until either another thread invokes the notify( ) method or the notifyAll( ) method for this object, or a specified amount of time has elapsed.?
譯:導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對(duì)象的notify() 方法或 notifyAll() 方法,或者指定的時(shí)間過完。
void wait(long timeout, int nanos)?
Causes the current thread to wait until another thread invokes the notify( ) method or the notifyAll( ) method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed.?
譯:導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對(duì)象的notify( ) 方法或 notifyAll( ) 方法,或者其他線程打斷了當(dāng)前線程,或者指定的時(shí)間過完。
上面是官方文檔的簡(jiǎn)介,下面我們根據(jù)官方文檔總結(jié)一下:
-
wait( ),notify( ),notifyAll( )都不屬于Thread類,而是屬于Object基礎(chǔ)類,也就是每個(gè)對(duì)象都有wait( ),notify( ),notifyAll( ) 的功能,因?yàn)槊總€(gè)對(duì)象都有鎖,鎖是每個(gè)對(duì)象的基礎(chǔ),當(dāng)然操作鎖的方法也是最基礎(chǔ)了。
-
當(dāng)需要調(diào)用以上的方法的時(shí)候,一定要對(duì)競(jìng)爭(zhēng)資源進(jìn)行加鎖,如果不加鎖的話,則會(huì)報(bào) IllegalMonitorStateException 異常
-
當(dāng)想要調(diào)用wait( )進(jìn)行線程等待時(shí),必須要取得這個(gè)鎖對(duì)象的控制權(quán)(對(duì)象監(jiān)視器),一般是放到synchronized(obj)代碼中。
-
在while循環(huán)里而不是if語句下使用wait,這樣,會(huì)在線程暫?;謴?fù)后都檢查wait的條件,并在條件實(shí)際上并未改變的情況下處理喚醒通知
-
調(diào)用obj.wait( )釋放了obj的鎖,否則其他線程也無法獲得obj的鎖,也就無法在synchronized(obj){ obj.notify() } 代碼段內(nèi)喚醒A。
-
notify( )方法只會(huì)通知等待隊(duì)列中的第一個(gè)相關(guān)線程(不會(huì)通知優(yōu)先級(jí)比較高的線程)
-
notifyAll( )通知所有等待該競(jìng)爭(zhēng)資源的線程(也不會(huì)按照線程的優(yōu)先級(jí)來執(zhí)行)
-
假設(shè)有三個(gè)線程執(zhí)行了obj.wait( ),那么obj.notifyAll( )則能全部喚醒tread1,thread2,thread3,但是要繼續(xù)執(zhí)行obj.wait()的下一條語句,必須獲得obj鎖,因此,tread1,thread2,thread3只有一個(gè)有機(jī)會(huì)獲得鎖繼續(xù)執(zhí)行,例如tread1,其余的需要等待thread1釋放obj鎖之后才能繼續(xù)執(zhí)行。
-
當(dāng)調(diào)用obj.notify/notifyAll后,調(diào)用線程依舊持有obj鎖,因此,thread1,thread2,thread3雖被喚醒,但是仍無法獲得obj鎖。直到調(diào)用線程退出synchronized塊,釋放obj鎖后,thread1,thread2,thread3中的一個(gè)才有機(jī)會(huì)獲得鎖繼續(xù)執(zhí)行。
2.wait和notify簡(jiǎn)單使用示例
public class WaitNotifyTest {// 在多線程間共享的對(duì)象上使用wait private String[] shareObj = { "true" }; public static void main(String[] args) { WaitNotifyTest test = new WaitNotifyTest(); ThreadWait threadWait1 = test.new ThreadWait("wait thread1"); threadWait1.setPriority(2); ThreadWait threadWait2 = test.new ThreadWait("wait thread2"); threadWait2.setPriority(3); ThreadWait threadWait3 = test.new ThreadWait("wait thread3"); threadWait3.setPriority(4); ThreadNotify threadNotify = test.new ThreadNotify("notify thread"); threadNotify.start(); threadWait1.start(); threadWait2.start(); threadWait3.start(); } class ThreadWait extends Thread { public ThreadWait(String name){ super(name); } public void run() { synchronized (shareObj) { while ("true".equals(shareObj[0])) { System.out.println("線程"+ this.getName() + "開始等待"); long startTime = System.currentTimeMillis(); try { shareObj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } long endTime = System.currentTimeMillis(); System.out.println("線程" + this.getName() + "等待時(shí)間為:" + (endTime - startTime)); } } System.out.println("線程" + getName() + "等待結(jié)束"); } } class ThreadNotify extends Thread { public ThreadNotify(String name){ super(name); } public void run() { try { // 給等待線程等待時(shí)間 sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (shareObj) { System.out.println("線程" + this.getName() + "開始準(zhǔn)備通知"); shareObj[0] = "false"; shareObj.notifyAll(); System.out.println("線程" + this.getName() + "通知結(jié)束"); } System.out.println("線程" + this.getName() + "運(yùn)行結(jié)束"); } } }?
運(yùn)行結(jié)果:
線程wait thread1開始等待 線程wait thread3開始等待 線程wait thread2開始等待 線程notify thread開始準(zhǔn)備通知 線程notify thread通知結(jié)束 線程notify thread運(yùn)行結(jié)束 線程wait thread2等待時(shí)間為:2998 線程wait thread2等待結(jié)束 線程wait thread3等待時(shí)間為:2998 線程wait thread3等待結(jié)束 線程wait thread1等待時(shí)間為:3000 線程wait thread1等待結(jié)束轉(zhuǎn)載于:https://www.cnblogs.com/eer123/p/7880789.html
總結(jié)
以上是生活随笔為你收集整理的wait和notify的理解与使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何实现对象克隆?
- 下一篇: 【20171123】【GITC精华演讲】