Java并发编程实战 第14章 构建自定义的同步工具
狀態(tài)依賴性
定義:只有滿足特定的狀態(tài)才能繼續(xù)執(zhí)行某些操作(這些操作依賴于固定的狀態(tài),這些狀態(tài)需要等待別的線程來滿足)。
FutureTask,Semaphroe,BlockingQueue等,都是狀態(tài)依賴性的類。
條件隊(duì)列
條件對(duì)列:條件對(duì)列就是由于不滿足繼續(xù)的條件而被wait操作阻塞的線程隊(duì)列。他們都在等待條件滿足,然后被喚醒。
條件謂詞:狀態(tài)依賴性依賴的前提條件。如BlockingQueue中的isFull,isEmpty等。
條件等待中存在三個(gè)要素:加鎖 + 條件謂詞 + wait方法
wait方法和notify方法
我理解的wait方法:會(huì)釋放鎖+阻塞當(dāng)前線程,放入條件對(duì)列,等待被喚醒,喚醒后,需要重新獲得鎖,獲得鎖之后繼續(xù)執(zhí)行wait那句代碼所在的位置(即使wait在鎖塊的中間代碼部分)。
notify(All)方法:只是喚醒條件隊(duì)列中的線程。但是不釋放鎖。
使用wait notify方法的時(shí)候,一定要持有條件對(duì)列所屬的鎖。
使用輪詢和休眠實(shí)現(xiàn)簡單的狀態(tài)依賴性阻塞
使用條件隊(duì)列來實(shí)現(xiàn)狀態(tài)依賴性阻塞
?
注意上面要使用while。
對(duì)于監(jiān)視器來說,wait操作產(chǎn)生的線程,都放在這個(gè)監(jiān)視器唯一的條件隊(duì)列里。
如果使用Lock,可以使用condition來產(chǎn)生不同的條件對(duì)列。
注意上面的?this.notifyAll();代碼,將會(huì)喚醒這個(gè)監(jiān)視器條件隊(duì)列里所有等待的線程。其實(shí)這里只用喚醒因?yàn)閑mpty阻塞的線程,而不用喚醒因?yàn)閒ull阻塞的線程。
如果使用?this.notify(),只會(huì)隨機(jī)喚醒一個(gè),如果喚醒的是因?yàn)閒ull堵塞的線程,那么就可能沒有正常喚醒。影響性能,甚至造成活躍性的危險(xiǎn)。
這種情況下,可以使用Lock和Condition來改造。
注意:這里不是signalAll。
閥門類
使用閉鎖CountDownLatch,傳入1的時(shí)候可以作為閥門開關(guān)。前提是在其他線程的第一步先執(zhí)行開關(guān)的await。使用開關(guān)的countDown方法就可以打開開關(guān)。
但是這種閥門,只能打開,不能關(guān)閉。
使用wait和notifyAll來實(shí)現(xiàn)可重新關(guān)閉的閥門。
Condition
注意,由于Condition對(duì)象繼承自O(shè)bject,它也有wait,notify,notifyAll方法,其實(shí)它對(duì)應(yīng)方法名字應(yīng)該是await,signal,signalAll。
?
轉(zhuǎn)載于:https://www.cnblogs.com/xiaolang8762400/p/7074721.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的Java并发编程实战 第14章 构建自定义的同步工具的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基础知识回顾——异常处理
- 下一篇: 九大排序算法Java实现