Lock的await/singal 和 Object的wait/notify 的區別
阿新 • • 發佈:2019-02-07
轉載http://www.cnblogs.com/alphablox/archive/2013/01/20/2868479.html
在使用Lock之前,我們都使用Object 的wait和notify實現同步的。舉例來說,一個producer和consumer,consumer發現沒有東西了,等待,produer生成東西了,喚醒。
執行緒consumer | 執行緒producer |
synchronize(obj){ obj.wait();//沒東西了,等待 } |
synchronize(obj){ obj.notify();//有東西了,喚醒 } |
有了lock後,世道變了,現在是:
lock.lock(); condition.await(); lock.unlock(); |
lock.lock(); condition.signal(); lock.unlock(); |
為了突出區別,省略了若干細節。區別有三點:
- 1. lock不再用synchronize把同步程式碼包裝起來;
- 2. 阻塞需要另外一個物件condition;
- 3. 同步和喚醒的物件是condition而不是lock,對應的方法是await和signal,而不是wait和notify。
為什麼需要使用condition呢?簡單一句話,lock更靈活。以前的方式只能有一個等待佇列,在實際應用時可能需要多個,比如讀和寫。為了這個靈活性,lock將同步互斥控制和等待佇列分離開來,互斥保證在某個時刻只有一個執行緒訪問臨界區(lock自己完成),等待佇列負責儲存被阻塞的執行緒(condition完成)。
通過檢視ReentrantLock的原始碼發現,condition其實是等待佇列的一個管理者,condition確保阻塞的物件按順序被喚醒。
在Lock的實現中,LockSupport被用來實現執行緒狀態的改變,後續將更進一步研究LockSupport的實現機制。