多線程--對象鎖與類鎖的區別

多線程--對象鎖與類鎖的區別

對象鎖

對象鎖:java中任何對象都擁有一個互斥鎖,當一個類中聲明瞭synchronized方法,或者在方法中聲明瞭參考(reference)對象爲this的synchronized代碼塊
則表示在此方法或者此代碼塊中該對象同時只能被同一個線程訪問。
例如類A有一個同步方法f1(),a1、a2兩個實例對象
當一個線程t1通過a1調用f1()時,此時t1擁有對象a1的鎖,與此同時:
1.當其他線程再次通過a1來調用f1時,此時需要等待t1將a1的鎖釋放才能進入,此時爲阻塞狀態。
2.當線程t2通過a2來調用f1()時,是不會阻塞的,因爲t1只是持有了a1的鎖並沒有持有a2的鎖。

類鎖

類鎖:java中類的所有實例化對象都屬於該類的class對象,當一個類中,擁有同步靜態方法,或者同步代碼塊使用類名.class修飾,那麼當前類只能同時被一個對象持有類鎖。此時該類的靜態成員,靜態方法,因爲都從屬於該類,所有隻能同時被一個該類實例對象訪問。

由於一個class不論被實例化多少次,其中的靜態方法和靜態變量在內存中都只有一份。所以,一旦一個靜態的方法被申明爲synchronized。此類所有的實例化對象在調用此方法,共用同一把鎖,我們稱之爲類鎖。

小結

對象鎖用來控制實例方法之間的同步,類鎖是用來控制靜態方法(或靜態變量互斥體)之間的同步。
 
對於類鎖,會把整個類鎖住,也就說只能有一個對象擁有當前類的鎖。當一個對象擁有了類鎖之後,另外一個對象還想競爭鎖的話則會被阻塞。
兩個對象A,B,如果A正在訪問一個被類鎖修飾的方法function,那麼B則不能訪問。因爲類鎖只能在同一時刻被一個對象擁有。相對於對象鎖,則不同:還是A,B兩個對象,如果A正在訪問對象鎖修飾的function,那麼這個時候B也可以同時訪問。

對象鎖(方法鎖),是針對一個對象的,它只在該對象的某個內存位置聲明一個標識該對象是否擁有鎖,所以它只會鎖住當前的對象,一般一個對象鎖是對一個非靜態成員變量進行synchronized修飾,或者對一個非靜態成員方法進行synchronized進行修飾,對於對象鎖,不同對象訪問同一個被synchronized修飾的方法的時候不會阻塞

拓展–可重入鎖

可重入鎖:對於對象鎖,當一個對象擁有鎖之後,訪問一個加了對象鎖的方法,而該方法中又調用了該類中其他加了對象鎖的方法,那麼這個時候是不會阻塞住的。

這是java通過可重入鎖機制實現的。可重入鎖指的是當一個對象擁有對象鎖之後,可以重複獲取該鎖。因爲synchronized塊是可重入的,所以當你訪問一個對象鎖的方法的時候,在該方法中繼續訪問其他對象鎖方法是不會被阻塞的。

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