java線程同步原理
來源:互聯網
上載者:User
一。 java線程同步原理
java會為每個object對象分配一個monitor,當某個對象的同步方法(synchronized methods)被多個線程調用時,該對象的monitor將負責處理這些訪問的並發獨佔要求。
當一個線程調用一個對象的同步方法時,JVM會檢查該對象的monitor。如果monitor沒有被佔用,那麼這個線程就得到了monitor的佔有權,可以繼續執行該對象的同步方法;如果monitor被其他線程所佔用,那麼該線程將被掛起,直到monitor被釋放。
當線程退出同步方法調用時,該線程會釋放monitor,這將允許其他等待的線程獲得monitor以使對同步方法的調用執行下去。
注意:Java對象的monitor機制和傳統的臨界檢查代碼區技術不一樣。java的一個同步方法並不意味著同時只有一個線程獨佔執行,但臨界檢查代碼區技術確實會保證同步方法在一個時刻只被一個線程獨佔執行。Java的monitor機制的準確含義是:任何時刻,對一個指定object對象的某同步方法只能由一個線程來調用。
java對象的monitor是跟隨object執行個體來使用的,而不是跟隨程式碼。兩個線程可以同時執行相同的同步方法,比如:一個類的同步方法是xMethod(),有a,b兩個對象執行個體,一個線程執行a.xMethod(),另一個線程執行b.xMethod().互不衝突。
二。 wait()、notify(),notifyAll()的使用
obj.wait()方法將使本線程掛起,並釋放obj對象的monitor。只有其他線程調用obj對象的notify()或notifyAll()時,才可以被喚醒。
obj.notifyAll()方法喚醒所有該obj對象相關的沉睡線程,然後被喚醒的眾多線程開始競爭obj對象的monitor佔有權,最終得到的那個線程會繼續執行下去,但其他線程還將繼續等待。
obj.notify()方法是隨機喚醒一個沉睡線程。
wait,notify和notifyAll只能在同步控制方法或者同步控制塊裡面使用,
如:
synchronized(x){
x.notify()
//或者wait()
}
以上內容說明了為什麼調用wait(),notify(),notifyAll()的線程必須要擁有obj執行個體對象的monitor佔有權。
每個對象執行個體都有一個等待線程隊列。這些線程都是等待對該對象的同步方法的調用許可。對一個線程來說,有兩種方法可以進入這個等待線程隊列。一個是當其他線程執行同步方法時,自身同時也要執行該同步方法;另一個是調用obj.wait()方法。
當同步方法執行完畢或者執行wait()時,其他某個線程將獲得對象的訪問權。當一個線程被放入等待隊列時,必須要確保可以通過notify()的調用來解凍該線程,以使其能夠繼續執行下去。
三。 wait()與sleep()的區別:
sleep()函數是Thread類的靜態函數,不涉及到線程間同步概念,僅僅為了讓一個線程自身獲得一段沉睡時間。sleep可以在任何地方使用。
wait函數是object類的函數,要解決的問題是線程間的同步,該過程包含了同步鎖的擷取和釋放,調用wait方法將會將調用者的線程掛起,直到其他線程調用同一個對象的notify方法才會重新啟用調用者。
注意,線程調用notify()之後,只有該線程完全從synchronized代碼裡面執行完畢後,monitor才會被釋放,被喚醒線程才可以真正得到執行權。