方法鎖、對象鎖、類鎖


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

類鎖是鎖住整個類,當有多個線程來聲明這個類的對象時候將會被阻塞,直到擁有這個類鎖的對象唄銷毀或者主動釋放了類鎖,這個時候在被阻塞的線程被挑選出一個占有該類鎖,聲明該類的對象。其他線程繼續被阻塞住。

無論是類鎖還是對象鎖,父類和子類之間是否阻塞沒有直接關系。當對一個父類加了類鎖,子類是不會受到影響的,相反也是如此。因為synchronized關鍵字並不是方法簽名的一部分,它是對方法進行修飾的。當子類覆寫父類中的同步方法或是接口中聲明的同步方法的時候,synchronized修飾符是不會被自動繼承的,所以相應的阻塞問題不會出現。

注意:這里的阻塞問題是指的按照正常情況下應該阻塞,而因為synchronized是父類與子類之間不可傳遞導致不會阻塞。那正常情況下阻塞是什么那,下面會詳細介紹。但是,當一個子類沒有覆蓋父類的方法的時候,這時候通過子類訪問方法則會產生阻塞。

插入一句:構造方法不可能是真正同步的(盡管可以在構造方法中使用同步塊)。下面截圖給出了如何聲明一個對象鎖和如何聲明一個類鎖:

1 void myMethod(){
 2     synchronized(this){
 3         //code
 4     }
 5 }
 6 
 7 /*is equvilant to*/
 8 void synchronized myMethod(){
 9     //code
10 }

當同一個對象在線程1中訪問一個方法,在線程2中再去訪問另外一個加鎖方法,則同樣也會被阻塞.

對於類鎖,則會把整個類鎖住,也就說只能有一個對象擁有當前類的鎖。當一個對象擁有了類鎖之后,另外一個對象還想競爭鎖的話則會被阻塞。兩個對象A,B,如果A正在訪問一個被類鎖修飾的方法function,那么B則不能訪問。因為類鎖只能在同一時刻被一個對象擁有。相對於對象鎖,則是不同。還是A,B兩個對象,如果A正在訪問對象鎖修飾的function,那么這個時候B也可以同時訪問。

對於對象鎖,當一個對象擁有鎖之后,訪問一個加了對象鎖的方法,而該方法中又調用了該類中其他加了對象鎖的方法,那么這個時候是不會阻塞住的。這是java通過可重入鎖機制實現的。可重入鎖指的是當一個對象擁有對象鎖之后,可以重復獲取該鎖。因為synchronized塊是可重入的,所以當你訪問一個對象鎖的方法的時候,在該方法中繼續訪問其他對象鎖方法是不會被阻塞的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM