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