JVM005_synchronized、同步指令、管程、MESA
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                JVM005_synchronized、同步指令、管程、MESA
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                synchronized、同步指令、管程、MESA
synchronized是Java的一個關鍵詞,可以保證方法或者代碼塊在運行時,同一時刻只有一個方法可以進入到臨界區,保證了原子性、可見性、有序性。
臨界資源一次只能被一個線程訪問的資源。
**臨界區:**訪問臨界資源的那段代碼。
synchronized的應用
synchronized可以修飾:
靜態方法,鎖定的是當前類的Class對象,進入同步代碼前需要先獲得當前類的鎖。
public class Test{public synchronized static int autoIncrement(int a){return a++;} }實例方法,鎖定的是當前實例對象,進入同步代碼前需要先獲得當前實例的鎖。
public class Test1{public synchronized int autoIncrement(int a){return a++;} }代碼塊,鎖定的是括號中的對象,進入同步代碼前需要先獲得指定對象的鎖。
public class Test2{public int autoIncrement(int a){// this 可以替換為任意指定對象synchronized(this){return a++; }} }synchronized與編譯
將上面的代碼使用javac -g命令編譯后,再利用javap -v命令進行匯編反編譯,再截取我們關注內容可以的到如下內容:
# 1修飾靜態方法public static synchronized int autoIncrement(int);descriptor: (I)Iflags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED # ACC_SYNCHRONIZED 訪問標志區分一個方法是否同步方法Code:stack=1, locals=1, args_size=10: iload_01: iinc 0, 14: ireturnLineNumberTable:line 5: 0LocalVariableTable:Start Length Slot Name Signature0 5 0 a I# 2修飾實例方法 public synchronized int autoIncrement(int);descriptor: (I)Iflags: ACC_PUBLIC, ACC_SYNCHRONIZED # ACC_SYNCHRONIZED 訪問標志區分一個方法是否同步方法Code:stack=1, locals=2, args_size=20: iload_11: iinc 1, 14: ireturnLineNumberTable:line 5: 0LocalVariableTable:Start Length Slot Name Signature0 5 0 this Lcom/lbc/springboot2/jvmlearn/Test1;0 5 1 a I # 3修飾代碼塊public int autoIncrement(int);descriptor: (I)Iflags: ACC_PUBLICCode:stack=2, locals=4, args_size=20: aload_01: dup2: astore_23: monitorenter # 獲取對象的鎖,進入同步方法或同步塊 -->>為什么虛擬機字節碼指令表中說進入同步方法呢?4: iload_15: iinc 1, 18: aload_29: monitorexit # 釋放對象的鎖,退出同步方法或同步塊10: ireturn11: astore_312: aload_213: monitorexit # 釋放對象的鎖,退出同步方法或同步塊14: aload_315: athrowException table:from to target type4 10 11 any11 14 11 anyLineNumberTable:line 6: 0line 7: 4line 8: 11可以看到當synchronized修飾實例方法或者靜態方法時,方法表集合中的方法訪問標志都有ACC_SYNCHRONIZED,它表示該方法是synchronized的。而在synchronized修飾代碼塊是,javac編譯后,會生成monitorenter,monitorexit指令,分別表示獲取對象的鎖、進入同步塊和釋放對象的鎖、退出同步塊。
那么為什么會有兩個monitorexit指令呢?第一個monitorexit是同步代碼塊正常執行完后釋放鎖,第二monitorexit表示有異常后,釋放鎖,保證不會因為異常導致無法釋放鎖。
– 待續
總結
以上是生活随笔為你收集整理的JVM005_synchronized、同步指令、管程、MESA的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: LeetCode算法入门- Palind
- 下一篇: Spring MVC 流程图解析
