這是一個老生常談的面試題了,wait
和 notify
配合監視器提供了多個同步線程之間通訊機制,答案自己也很簡單,因爲通訊自己解決的就是鎖的歸屬問題(發現當前應該把鎖給別人時調用 wait
, 通知別人能夠來用鎖了調用 notify
),從功能上講,放在 Object
類(鎖對象)中本就是理所固然的。java
但咱們能夠換個角度去思考,不妨使用假設法,假設 wait
和 notify
是放在 Thread
類中,看看使用的狀況會是怎麼樣的。面試
因爲線程之間並不知道其餘對象獲取鎖的狀況,須要額外的開銷去記錄和遍歷其餘線程的狀況,而且一個線程其實是能夠擁有多個鎖的。所以,要實現線程通訊機制,有兩個必不可少的參數,線程和鎖對象。併發
synchronized(lock) {
Thread.currentThread().wait(lock);
}
複製代碼
若是是這麼使用的話其實沒有什麼問題,從功能上來講其實和 lock.wait()
沒有什麼區別。可是,只要有存在的可能,就必定會發生。有些人可能恰好因爲契合某些業務來實現某些功能會寫出如下代碼:spa
List<Thread> threadList = ...
synchronized(lock) {
threadList.get(i).wait(lock);
}
複製代碼
在當前線程的代碼容許其餘的線程在所需的鎖上等待,這種「入侵」式的代碼給設計和維護帶來了許多的困難,本來併發程序就很差調式,這樣一來就更加的混亂,而且產生沒法預計和復現的錯誤。畢竟可能讓使用者產生錯誤用法的設計就不是一個好的設計。線程