java多線程(2) ----- synchronized對象監視器爲Object時的使用(上)

(歡迎關注微信公衆號:深入Java底層)

synchronized同步方法/synchronized(this)同步代碼塊

·同一時間只有一個線程可以執行synchronized同步方法/synchronized(this)同步代碼塊中的代碼。

·對其他synchronized同步方法或synchronized(this)同步代碼調用呈阻塞狀態。

synchronized(非this對象x)同步代碼塊

·當多個線程同時執行synchronized(x){}同步代碼塊時呈同步效果。

·當其他線程執行x對象中synchronized同步方法時呈同步效果。

·當其他線程執行x對象方法裏面的synchronized(this)代碼塊時也呈現同步效果。

但需要注意:如果其他線程調用不加synchronized關鍵字的方法時,還是異步調用。

synchronized鎖重入

關鍵字synchronized擁有鎖重入的功能,也就是在使用synchronized時,當一個線程得到一個對象鎖後,再次請求此對象鎖時是可以再次得到該對象的鎖的。這也證明在一個synchronized方法/塊的內部調用本類的其他synchronized方法/塊時,是永遠可以得到鎖的。

當存在父子類繼承關係時,子類是完全可以通過“可重入鎖”調用父類的同步方法的。

出現異常,鎖自動釋放

當一個線程執行的代碼出現異常時,其持有的鎖會自動釋放。

同步不具有繼承性

同步不能繼承,要想子類方法也有同步效果,子類方法也要添加synchronized關鍵字。

數據類型String的常量特性

在JVM中具有String常量池緩存的功能,同步synchronized代碼塊中使用String作爲鎖對象時,兩個string鎖對象有可能是同一個鎖對象。在大多數的情況下,同步synchronized代碼塊都不使用String作爲鎖對象,而改用其他,比如new Object()實例化一個Object對象,但它並不放入緩存中,這樣就是兩個不同的鎖對象

同步synchronized方法無限等待與解決

一個類中多個同步方法,如果其中一個同步方法無限循環,其他同步方法將無限等待,永遠得不到運行的機會。這時就可以使用同步塊來解決這樣的問題,同步塊之間使用不同的對象鎖。

多線程的死鎖

Java線程死鎖是一個經典的多線程問題,因爲不同的線程都在互相等待對方釋放鎖,從而導致所有的任務都無法繼續完成,出現死鎖。在多線程技術中,“死鎖”是必須避免的,因爲這會造成線程的“假死”。

可以使用JDK自帶的工具來監測是否有死鎖的現象。首先進入CMD工具,再進入JDK安裝文件夾中的bin目錄,執行jps命令,如2-57所示。


得到運行的線程Run的id值是3244。再執行jstack命令,查看結果,如果2-58所示。


監測出有死鎖現象,如圖2-59所示。

內置類與靜態內置類

實例化內置類:

PublicClasspublicClass = new PublicClass ();

PrivateClass privateClass = publicClass.new PrivateClass();

實例化靜態內置類:

PrivateClass privateClass = new PrivateClass();

在內置類中持有不同鎖的同步方法,異步執行;同步代碼塊synchronized(class2)對內置類class2上鎖後,其他線程只能以同步的方法調用class2中的靜態同步方法。

鎖對象的改變

·如果多個線程共同爭搶的鎖資源在邏輯處理過程發生了改變,那麼線程之間是異步的。(如果多個線程同時獲取鎖,鎖對象的值有可能還沒來得及改變,就已經完成鎖爭搶的動作,此時線程之間還是同步運行)

·只要對象不變,即使對象的屬性被改變,運行結果還是同步的。

(歡迎關注微信公衆號:深入Java底層)



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章