日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

JVM005_synchronized、同步指令、管程、MESA

發(fā)布時(shí)間:2025/3/12 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JVM005_synchronized、同步指令、管程、MESA 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

synchronized、同步指令、管程、MESA

synchronized是Java的一個(gè)關(guān)鍵詞,可以保證方法或者代碼塊在運(yùn)行時(shí),同一時(shí)刻只有一個(gè)方法可以進(jìn)入到臨界區(qū),保證了原子性、可見性、有序性。

臨界資源一次只能被一個(gè)線程訪問(wèn)的資源。

**臨界區(qū):**訪問(wèn)臨界資源的那段代碼。

synchronized的應(yīng)用

synchronized可以修飾:

  • 靜態(tài)方法,鎖定的是當(dāng)前類的Class對(duì)象,進(jìn)入同步代碼前需要先獲得當(dāng)前類的鎖。

    public class Test{public synchronized static int autoIncrement(int a){return a++;} }
  • 實(shí)例方法,鎖定的是當(dāng)前實(shí)例對(duì)象,進(jìn)入同步代碼前需要先獲得當(dāng)前實(shí)例的鎖。

    public class Test1{public synchronized int autoIncrement(int a){return a++;} }
  • 代碼塊,鎖定的是括號(hào)中的對(duì)象,進(jìn)入同步代碼前需要先獲得指定對(duì)象的鎖。

    public class Test2{public int autoIncrement(int a){// this 可以替換為任意指定對(duì)象synchronized(this){return a++; }} }
  • synchronized與編譯

    將上面的代碼使用javac -g命令編譯后,再利用javap -v命令進(jìn)行匯編反編譯,再截取我們關(guān)注內(nèi)容可以的到如下內(nèi)容:

    # 1修飾靜態(tài)方法public static synchronized int autoIncrement(int);descriptor: (I)Iflags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED # ACC_SYNCHRONIZED 訪問(wèn)標(biāo)志區(qū)分一個(gè)方法是否同步方法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修飾實(shí)例方法 public synchronized int autoIncrement(int);descriptor: (I)Iflags: ACC_PUBLIC, ACC_SYNCHRONIZED # ACC_SYNCHRONIZED 訪問(wèn)標(biāo)志區(qū)分一個(gè)方法是否同步方法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 # 獲取對(duì)象的鎖,進(jìn)入同步方法或同步塊 -->>為什么虛擬機(jī)字節(jié)碼指令表中說(shuō)進(jìn)入同步方法呢?4: iload_15: iinc 1, 18: aload_29: monitorexit # 釋放對(duì)象的鎖,退出同步方法或同步塊10: ireturn11: astore_312: aload_213: monitorexit # 釋放對(duì)象的鎖,退出同步方法或同步塊14: aload_315: athrowException table:from to target type4 10 11 any11 14 11 anyLineNumberTable:line 6: 0line 7: 4line 8: 11

    可以看到當(dāng)synchronized修飾實(shí)例方法或者靜態(tài)方法時(shí),方法表集合中的方法訪問(wèn)標(biāo)志都有ACC_SYNCHRONIZED,它表示該方法是synchronized的。而在synchronized修飾代碼塊是,javac編譯后,會(huì)生成monitorenter,monitorexit指令,分別表示獲取對(duì)象的鎖、進(jìn)入同步塊和釋放對(duì)象的鎖、退出同步塊。

    那么為什么會(huì)有兩個(gè)monitorexit指令呢?第一個(gè)monitorexit是同步代碼塊正常執(zhí)行完后釋放鎖,第二monitorexit表示有異常后,釋放鎖,保證不會(huì)因?yàn)楫惓?dǎo)致無(wú)法釋放鎖。

    – 待續(xù)

    總結(jié)

    以上是生活随笔為你收集整理的JVM005_synchronized、同步指令、管程、MESA的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。