天天看點

[Java] 方法鎖、對象鎖和類鎖的意義和差別 方法鎖(synchronized修飾方法時)  對象鎖(synchronized修飾方法或代碼塊)類鎖(synchronized 修飾靜态的方法或代碼塊)

版權聲明:請尊重個人勞動成果,轉載注明出處,謝謝!

synchronized  在修飾代碼塊的時候需要一個reference對象作為鎖的對象.  在修飾方法的時候預設是目前對象作為鎖的對象.  在修飾類時候預設是目前類的class對象作為鎖的對象.  <a href="http://blog.csdn.net/amazing7/article/details/51219714">線程同步的方法:sychronized、lock、reentrantlock分析</a>

通過在方法聲明中加入 synchronized關鍵字來聲明 synchronized 方法。

synchronized 方法控制對類成員變量的通路: 

每個類執行個體對應一把鎖,每個 synchronized 方法都必須獲得調用該方法的類執行個體的鎖方能執行,否則所屬線程阻塞,方法一旦執行,就獨占該鎖,直到從該方法傳回時才将鎖釋放,此後被阻塞的線程方能獲得該鎖,重新進入可執行狀态。這種機制確定了同一時刻對于每一個類執行個體,其所有聲明為 synchronized 的成員函數中至多隻有一個處于可執行狀态,進而有效避免了類成員變量的通路沖突。

  當一個對象中有synchronized method或synchronized block的時候調用此對象的同步方法或進入其同步區域時,就必須先獲得對象鎖。如果此對象的對象鎖已被其他調用者占用,則需要等待此鎖被釋放。(方法鎖也是對象鎖)        

java的所有對象都含有1個互斥鎖,這個鎖由jvm自動擷取和釋放。線程進入synchronized方法的時候擷取該對象的鎖,當然如果已經有線程擷取了這個對象的鎖,那麼目前線程會等待;synchronized方法正常傳回或者抛異常而終止,jvm會自動釋放對象鎖。這裡也展現了用synchronized來加鎖的1個好處,方法抛異常的時候,鎖仍然可以由jvm來自動釋放。 

對象鎖的兩種形式:

  由于一個class不論被執行個體化多少次,其中的靜态方法和靜态變量在記憶體中都隻有一份。是以,一旦一個靜态的方法被申明為synchronized。此類所有的執行個體化對象在調用此方法,共用同一把鎖,我們稱之為類鎖。   

對象鎖是用來控制執行個體方法之間的同步,類鎖是用來控制靜态方法(或靜态變量互斥體)之間的同步。  

類鎖隻是一個概念上的東西,并不是真實存在的,它隻是用來幫助我們了解鎖定執行個體方法和靜态方法的差別的。  

java類可能會有很多個對象,但是隻有1個class對象,也就是說類的不同執行個體之間共享該類的class對象。class對象其實也僅僅是1個java對象,隻不過有點特殊而已。由于每個java對象都有1個互斥鎖,而類的靜态方法是需要class對象。是以所謂的類鎖,不過是class對象的鎖而已。擷取類的class對象有好幾種,最簡單的就是[類名.class]的方式。