Java併發—Synchronized 的本質
使用場景
先用一張圖來描述使用的場景(圖片獲取至其他網站。)
總體來說就是方法和代碼塊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。