天天看點

sychronized的實作原理和應用

一、synchronized的使用

1.1修飾方法
public synchronized void method()
{
   // todo
}      
1.2修飾代碼塊
public  void run() {
          synchronized(this) {
             for (int i = 0; i < 5; i++) {
                try {
                   Thread.sleep(100);
                } catch (Exception e) {
                   e.printStackTrace();
                }
             }
          }
       }      
1.3修飾靜态方法
public synchronized static void method() {
   // todo
}      
1.4修飾一個類
class ClassName {
   public void method() {
      synchronized(ClassName.class) {
         // todo
      }
   }
}      

對于普通方法,鎖是目前執行個體對象

對于靜态同步方法,鎖是目前類的Class對象

對于同步方法快,鎖是Synchonized括号裡配置的對象

二、對象鎖的分析

當一個線程試圖通路同步代碼塊時,它首先必須得到鎖,退出或抛出異常是必須釋放鎖

鎖是怎麼實作代碼同步的:

sychronized的實作原理和應用

 這裡有個minitor對象,其特點是:在同一時間,隻有一個線程/程序能進入monitor所定義的臨界區,這使得monitor可以實作互斥的效果,無法進入monitor臨界區的程序/線程被阻塞,在适當的時候被喚醒

java對象存儲在記憶體中分為三部分:對象頭、執行個體資料和對齊填充,對象頭中存儲了鎖辨別

java對象頭分析:

sychronized的實作原理和應用

 Java對象頭裡的Mark Word裡預設存儲對象的HashCode、分代年齡和鎖标記位

sychronized的實作原理和應用

運作期間,Mark Word裡存儲的資料會随着鎖标志位的變化而變化。Mark Word可能變化為存儲一下4種資料 

sychronized的實作原理和應用

鎖對象基本原理:

sychronized的實作原理和應用

 當一個線程需要擷取Object的鎖時,會被放入EntrySet中進行等待,已經擷取到鎖的線程在缺少謀些外界條件的情況下,可能無法繼續進行,那麼線程就通過wait()方法将鎖釋放

進入wait Set區進行等待,當外部條件滿足時,先被阻塞的線程就先進去EnterySet區去競争鎖,這個外界條件在monitor機制中被稱為條件變量

三、鎖的更新

JavaSE1.6中鎖一共有四種狀态:從低到高依次是:無鎖狀态、偏向鎖狀态、輕量級鎖狀态和重量級鎖狀态

偏向鎖:

繼續閱讀