Java synchronized輕量級鎖實現過程淺析

一、什麼是輕量級鎖

輕量級鎖是JDK 6之中加入的新型鎖機制,它名字中的“輕量級”是相對於使用monitor的傳統鎖而言的。輕量級鎖指的是存在多線程競爭,但是任意時刻最多隻允許一個線程競爭獲得鎖,即不存在鎖競爭太過激烈的情況,輕量級鎖情況下,線程不會發生阻塞。

二、為什麼引入輕量級鎖

輕量級鎖考慮的是競爭鎖對象的線程不多,而且線程持有鎖的時間也不長的場景。因為阻塞線程需要CPU從用戶態轉到內核態,代價比較大,如果剛剛阻塞不久這個鎖就被釋放瞭,那這個代價就有點得不償失瞭,因此這個時候就幹脆不阻塞這個線程,讓它自旋這等待鎖的釋放。

三、輕量級鎖的升級時機

主要有兩個:

1)、關閉偏向鎖功能

使用 -XX:-UseBiasedLocking參數關閉偏向鎖,此時默認進入輕量級鎖;

2)、多個線程競爭偏向鎖

偏向鎖狀態下,由於別的線程嘗試競爭偏向鎖,並且CAS更新MarkWord中線程ID失敗,此時發生【偏向鎖 -> 輕量級鎖】升級;

舉個例子:

1、線程A先獲取到鎖對象,線程B又過來嘗試競爭這個鎖,此時該鎖已是偏向鎖偏向線程A瞭;

2、線程B嘗試執行CAS去替換鎖對象MarkWord中線程ID,看下能不能獲取到鎖;

3、如果線程B的CAS成功瞭,說明此時線程A執行完瞭同步塊代碼,這個時候線程B會直接替換鎖對象MarkWord中線程ID為自己的線程ID,該鎖不會發生升級,還是處於偏向鎖狀態;

4、如果線程B的CAS失敗瞭,說明線程A還沒執行完同步塊代碼,這個時候,偏向鎖就會升級為輕量級鎖(偏向鎖標識置為0,同步鎖標識置為00),這個輕量級鎖由原來持有偏向鎖的線程A持有,繼續執行同步代碼,此時正在競爭的線程B會進入CAS自旋等待獲取這個輕量級鎖;

四、輕量級鎖的演示

前面我們瞭解到,當關閉偏向鎖功能的時候,默認獲取的是輕量級鎖。所以我們這裡添加運行時參數 -XX:-UseBiasedLocking參數禁用偏向鎖。

public class LightweightLockDemo01 {
    public static void main(String[] args) {
        // 關閉偏向鎖,默認進入輕量級鎖
        Object objLock = new Object();
        new Thread(() -> {
            synchronized (objLock) {
                System.out.println(ClassLayout.parseInstance(objLock).toPrintable());
            }
        }, "t1").start();
    }
}

可以看到,對象頭最後三位為“000”,表示當前獲取的是一把輕量級鎖。

五、輕量級鎖的原理

輕量級鎖的加鎖

1)、JVM會在當前線程的棧幀中建立一個名為鎖記錄(Lock Record)的空間,用於存儲鎖對象目前的Mark Word的拷貝(官方稱為Displaced Mark Word)。若一個線程獲得鎖時發現是輕量級鎖,它會將對象的Mark Word復制到棧幀中的鎖記錄Lock Record中(Displaced Mark Word裡面);

2)、線程嘗試利用CAS操作將對象的Mark Word更新為指向Lock Record的指針,如果成功表示當前線程競爭到鎖,則將鎖標志位變成00,執行同步操作;

3)、如果失敗,表示MarkWord已經被替換成瞭其他線程的鎖記錄,說明在與其他線程搶占競爭鎖,當前線程就嘗試使用自旋來獲取鎖;

註意,JVM采用的是自適應自旋,也就是說,自適應意味著自旋的次數不是固定不變的,JVM會根據同一個鎖上一次自旋的時間以及擁有鎖線程的狀態來決定到底需要自旋多少次。JVM針對那些很少會自旋成功的線程,那麼下次會減少自旋的次數甚至壓根不自旋,避免CPU空轉。

輕量級鎖的釋放

輕量級鎖的釋放也是通過CAS操作來進行的,當前線程使用CAS操作將Displaced Mark Word的內存復制回鎖對象的MarkWord中,如果CAS操作替換成功,則說明釋放鎖成功;如果CAS自旋多次還是替換失敗的話,說明有其他線程嘗試獲取該鎖,則需要將輕量級鎖膨脹升級為重量級鎖;

六、輕量級鎖升級為重量級鎖的流程

七、輕量級鎖的優缺點

優點

在多線程交替執行同步塊的情況下,可以避免重量級鎖引起的性能消耗;

缺點

如果長時間自旋後還沒競爭到鎖,將會過度耗費CPU,即CPU空轉;

到此這篇關於Java synchronized輕量級鎖實現過程淺析的文章就介紹到這瞭,更多相關Java synchronized 內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: