一 、等待/通知機(jī)制介紹?
兩線程存在生產(chǎn)和消費(fèi)者關(guān)系液荸,如while,問題:不停輪詢機(jī)脱篙。浪費(fèi)CPU娇钱,間隔太大取不到。(wait/notify)解決
線程A調(diào)用對象O的wait()進(jìn)入等待狀態(tài)绊困,B調(diào)用對象Onotify()/notifyAll()文搂,A收通知后退出等待隊(duì)列,運(yùn)行
相關(guān)方法
notify() :通知“一個(gè)線程”
notifyAll():?“全部線程”?退出等待秤朗,優(yōu)先級煤蹭、隨機(jī)執(zhí)行,取決于JVM
wait():釋放共享資源鎖取视,等待硝皂,直到被喚醒
wait(long)n毫秒,沒有通知就超時(shí)返回????wait(long作谭,int)納秒
二 等待/通知機(jī)制的實(shí)現(xiàn)?
從運(yùn)行結(jié)果:”wait end 1521967322359”最后輸出可以看出稽物,notify()執(zhí)行后并不會立即釋放鎖。先進(jìn)入就緒折欠,再嘗試獲取
2.2? 線程基本狀態(tài)
2.?可運(yùn)行(runnable):start()進(jìn)運(yùn)行線程池姨裸,等待被線程調(diào)度選中,獲取cpu使用權(quán)怨酝。?
4.?阻塞(block):放棄cpu使用權(quán)傀缩,讓出cpu timeslice,分三種:
? ??等待阻塞:執(zhí)行o.wait()农猬,JVM把該線程放入waitting queue
????同步阻塞:該同步鎖被占用赡艰,放鎖池lock pool
????其他阻塞: 運(yùn)行線程執(zhí)行sleep(long ms)或t.join(),或者發(fā)出I/O請求時(shí)斤葱,JVM把線程置為阻塞慷垮。處理完畢轉(zhuǎn)入runnable
5.?死亡(dead):run()、main()結(jié)束揍堕,異常退出了run()方法料身,不可再次復(fù)生。
2.3 notify()鎖不釋放
當(dāng)方法wait()被執(zhí)行后衩茸,鎖自動被釋放芹血,但執(zhí)行完notify()方法后,鎖不會自動釋放。必須執(zhí)行完notify()方法所在的synchronized代碼塊后才釋放幔烛。
https://github.com/Snailclimb/threadDemo/tree/master/src/wait_notifyHoldLock)
三個(gè)同對象實(shí)例線程a,b,c:a執(zhí)行帶wait方法synchronized代碼塊啃擦、b,c執(zhí)行帶notify方法synchronized代碼塊
2.4 當(dāng)interrupt方法遇到wait方法
wait時(shí)饿悬,調(diào)用interrupt出現(xiàn)InterrupedException
Test.java
運(yùn)行結(jié)果:?