《java多線程編程核心技術》讀書筆記2.1

第二章 對象及變量的併發訪問


本節主要總結了一些synchronized的使用方法:

在java中:“非線程安全”的問題存在於“實例變量”中,如果是方法內部的私有變量,則不存在“非線程安全“的問題。


synchronized加在方法的前部:

       synchronized取得的鎖都是對象鎖,而不是把一段代碼或方法當作鎖,在線程的執行過程當中,哪個線程先執行了帶synchronized關鍵字的方法,哪個線程就持有該方法所屬對象的鎖,那麼其他線程只能等待,前提是多個線程訪問的是同一個對象的synchronized方法。如果多個線程訪問多個對象,則JVM會創建多個鎖。

     如果一個線程已經持有了一個對象的鎖,另外一個線程則不能訪問該對象的同步方法,但是可以訪問該對象的非同步方法。


    同步不具有繼承性,如果父類的某個方法擁有synchronized關鍵字,子類的該方法若想同步必須手動的加入synchronized關鍵字;


synchronized同步代碼塊synchronized(this):一個線程如果訪問了同步代碼塊中的代碼,另一個線程不可以訪問該對象的任何同步代碼塊,但可以訪問非同步代碼塊。同步代碼塊鎖定的也是當前對象。


將任意對象作爲監視器:synchronized(非this對象)

在多線程持有對像監視器爲同一個對象的前提下,同一時間只有一個線程可以執行synchronized(非this對象)中的同步代碼塊

當持有對象監視器爲同一個對象的前提下,同一時間只有一個線程可以執行synchronized(非this對象)同步代碼塊中的代碼。



三個結論:

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

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

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

如果其他線程調用不加synchronized關鍵字方法時,還是異步調用。


靜態同步:有兩種一種在靜態方法前面加上synchronized關鍵字,一種是synchronize(class)

關鍵字加到static方法上是給Class上鎖,加到非static是給對象上鎖。


class鎖可以對類的所有實例起作用,即就是在任何時候,只能有一個線程訪問該類的static方法。因爲static方法就是類方法。




關於鎖是字符串的情況:

     由於java中String常量池的存在,在程序中str1 = "AA",與str1 = "AA"實際是指向一個形同的對象,所以在應用鎖的時候synchronized(str1)與synchronized(str2)請求的是同一個鎖。因此在大多數情況下,同步synchronized代碼塊都不使用String作爲鎖對象。改用其他的。


爲了避免線程的長時間等待,應儘可能的使用synchronized同步代碼塊,少用synchronized方法。


在任何數據類型作爲同步鎖時,需要注意的是,是否有多個線程同時持有鎖對象,如果同時持有相同的鎖對象,則這些線程之間是同步的,如過分別獲得鎖對象,則這些線程之間是非同步的。















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