在使用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的實現機制。
http://blog.csdn.net/jihaitaowangyi/article/details/52852693