JIT對鎖的優化- 鎖消除和鎖粗化案例分析


鎖消除和鎖粗化案例分析

鎖消除

  • 直接上代碼
/**
 * 描述:  鎖粒度演示
 * @author karl
 * @create 2020-02-11 14:38
 */
public class MySynchronizedTest07 {
    private Object object = new Object();


    public void method() {
        synchronized (object) {
            System.out.println("hello  world");
        }
    }

}
  • 上述是一個簡單的同步代碼塊的案例,在並發的情況下多個線程是共享MySynchronizedTest07 的成員變量 object所以才達到了鎖的效果。
  • 我們再看下面一個案例代碼:
package com.karl.concurrent.syn;

/**
 * 描述:  鎖粒度演示
 *
 * @author karl
 * @create 2020-02-11pw 14:38
 */
public class MySynchronizedTest07 {

    public void method() {
        Object object = new Object();
        synchronized (object) {
            System.out.println("hello  world");
        }
    }
}
  • 上述代碼我們可知將object變成了局部變量,在方法中,方法的的局部變量時線程獨立的,並發的場景每個線程都有各自的object對象,這個時候的鎖就無意義的。
  • 我們在編譯上述代碼的時候其實也發現了monitorenter和monitorexit,在字節碼層面看上去還有有鎖的獲取和釋放。
  • 這個時候JIT編譯器可以在動態編譯同步代碼的時候,使用一種叫做逃逸分析的技術(后續學習jvm的時候會涉及到),來通過該技術判斷程序中使用的鎖對象是否只被一個線程所使用。而沒有別的線程進行競爭。當這種情況的下,那么JIT編譯器在編譯(將字節碼編程機器碼)這個同步代碼時就不會生成synchronized關鍵字所標識鎖的申請和釋放的機器碼。從而消除鎖的使用流程。這就是鎖消除的原理和案例。

鎖粗化

  • 直接上代碼:

/**
 * 描述:  鎖粗化
 *
 * @author karl
 * @create 2020-02-11 15:15
 */
public class MySynchronizedTest08 {

    private Object object = new Object();


    public void method() {
        synchronized (object) {
            System.out.println("hello");
        }

        synchronized (object) {
            System.out.println("world");
        }

        synchronized (object) {
            System.out.println("!");
        }
    }
}
  • 代碼很簡單,在這里就不用做代碼解釋了
  • 我們直接看JIt編譯器如何優化上述代碼的。
  • JIT編譯器在執行動態編譯的時候。若發現前后相鄰的synchronized塊使用的是同一個鎖對象,那么它就會把這幾個synchronized塊合並成一個較大的同步快,這樣做的好處在於線程執行這些代碼的時候,就無需頻繁申請和釋放鎖了,從而達到申請與釋放一次就可以執行全部的同步代碼塊,從而提高了性能。

總結

  • 由於JIT編譯后的是機器碼,不能實際的去操作相應的優化效果。所以先理解理論即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM