使用場景

先用一張圖來描述使用的場景(圖片獲取至其他網站。)

總體來說就是方法和代碼塊2種方式。

代碼塊的同步

每個object在設計的時候,都是可以被monitor的,被鎖住的,所以使用計數器的方式就可以解決這個鎖的問題。

方法同步

這個按上一篇說講,就是方法通過ACC_SYNCHRONIZED標誌位來控制鎖。

xxx.class鎖住的是什麼?

只有static的方法可以synchronized xxx.class,那這個xxx.class是什麼。

我們先理解static method是什麼。按照深入理解JVM的說法,static的本質是一套命名方式,也就是與實例xxx class沒有任何本質的關係。

那這些static的方法是存在方法區的固定code,不需要實例化。

我們在回來看這個問題,當實例對象的方法被synchronized的時候,它同步鎖住的是什麼?就是this。雖然在JVM實現的時候不同,但是在更底層的時候是一樣的。

在會過來,既然鎖最終是總過對象來持有monitor的,那static的方法,是誰持有?synchroinzed的是什麼?

我們繼續反編譯代碼來分析

public static void testB();
    Code:
       0: ldc           #2                  // class com/demanmath/androidms/javabase/concurrent/SynchronizedDemo
       2: dup
       3: astore_0
       4: monitorenter
       5: iconst_0
       6: istore_1
       7: aload_0
       8: monitorexit
       9: goto          17
      12: astore_2
      13: aload_0
      14: monitorexit
      15: aload_2
      16: athrow
      17: return
    Exception table:
       from    to  target type
           5     9    12   any
          12    15    12   any

基本和非static的方法是一直的。也就是也有一個東西,被monitor了

這個東西就是可以被索引這個static方法的Class。所以Synchronized的就是這個Class。對,不是實例,是這個Class。

相關文章