JDK之synchronized字節碼分析

    先上一段代碼,以下:java

    List-1bash

public class Example2_synchronizer {

    @Test
    public void test1(){
        synchronized (this){
            int i=10;
            int j=i+1245;
        }
    }
}

    以後用在命令行輸入javap -v -p Example2_synchronizer,獲得以下片斷:性能

    List-2  javap的結果優化

3: monitorenter
         4: bipush        10
         6: istore_2
         7: iload_2
         8: sipush        1245
        11: iadd
        12: istore_3
        13: aload_1
        14: monitorexit
        15: goto          25
        18: astore        4
        20: aload_1
        21: monitorexit
        22: aload         4
        24: athrow
        25: return

    這就是平時說的monitorenter、monitorexit,值得注意的是,有倆個monitorexit。爲何會有倆個monitorexit,由於:若是synchronized塊裏面的代碼拋出異常,那麼會執行1八、20、2一、2二、24編號處的指令,它是在釋放以前獲取的鎖。因此Java中synchronized中即便拋出異常,JVM也會釋放鎖,讓其它線程獲取該鎖。有點像咱們操做文件時try{}catch{}finally{關閉文件流}。this

    來看下JVM 規範裏面給出的例子:.net

                                                           圖1 Java7的JVM規範中給出的例子                                  命令行

    synchronized的實現時在JVM代碼中的,synchronized是經過對象的monitorenter/monitorexit來實現的,JVM中有三種不一樣的monitor實現,也就是咱們說的偏向鎖、輕量級鎖、重量級鎖。爲何要引入這麼多實現,是爲了該善性能。Java利用CAS(compare and swap),在對象頭部的mark word處設置線程ID,表示該對象被被線程佔有。線程

    鎖的升級、降級,就是JVM優化synchronized運行的機制。鎖的升級是指從偏向鎖升級到輕量級鎖,從輕量級鎖升級到重量級鎖,如何作到的呢?待後面分析code

    鎖共有4種狀態,級別從低到高依次爲:無狀態鎖,偏向鎖,輕量級鎖和重量級鎖狀態,因爲是4種狀態,因此用JVM中用2bits能夠表示鎖的狀態。對象

 

    這篇博客也講的比較深刻:http://www.javashuo.com/article/p-rjpptcfl-cg.html

相關文章
相關標籤/搜索