天天看點

06synchronized

synchronized的作用是實作線程間同步,它的工作是對同步代碼塊加鎖,使得每一次隻能有一個線程進入同步塊,進而保證線程間安全性。

synchronized有三種用法:

  1. 指定加鎖對象:對給定的對象加鎖,進入同步代碼塊前要獲得給定對象的鎖。
  2. 直接作用于執行個體方法:相當于對目前執行個體加鎖,進入同步代碼塊前要獲得目前執行個體的鎖。
  3. 直接作用于靜态方法:相當于對目前類加鎖,進入同步代碼塊前要獲得目前類的鎖

JVM基于進入和退出Monitor對象來實作方法同步和代碼塊同步。

monitorenter指令是在編譯後插入到同步代碼塊的開始位置,而monitorexit是插入到方法結束處和異常處,JVM要保證每個monitorenter必須有對應的monitorexit與之配對。任何對象都有一個monitor與之關聯,當且一個monitor被持有後,它将處于鎖定狀态。線程執行到monitorenter指令時,将會嘗試擷取對象所對應的monitor的所有權,即嘗試獲得對象的鎖。

synchronized用的鎖是存在Java對象頭裡的。

public class Synchronized {
      public static void main(String[] args) {
           // 對Synchronized Class對象進行加鎖
           synchronized (Synchronized.class) {
           }
           // 靜态同步方法,對Synchronized Class對象進行加鎖
           m();
      }
      public static synchronized void m() {
      }
}      

在Synchronized.class同級目錄執行javap–v Synchronized.class部分相關輸出

public static void main(java.lang.String[]);
       // 方法修飾符,表示:public staticflags: ACC_PUBLIC, ACC_STATIC
      Code:
           stack=2, locals=1, args_size=1
           0: ldc       #1  // class com/murdock/books/multithread/book/Synchronized
           2: dup 
           3: monitorenter  // monitorenter:螢幕進入,擷取鎖
           4: monitorexit   // monitorexit:螢幕退出,釋放鎖
           5: invokestatic  #16 // Method m:()V
           8: return
    public static synchronized void m();
    // 方法修飾符,表示: public static synchronized
    flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED
           Code:
                   stack=0, locals=0      

實時内容請關注微信公衆号

上一篇: sum() over