1. 程式人生 > 其它 >Java有哪幾種鎖?分別有什麼特點?

Java有哪幾種鎖?分別有什麼特點?

根據分類標準我們把鎖分為以下 7 大類別,分別是:

  1. 偏向鎖/輕量級鎖/重量級鎖;
  2. 可重入鎖/非可重入鎖;
  3. 共享鎖/獨佔鎖;
  4. 公平鎖/非公平鎖;
  5. 悲觀鎖/樂觀鎖;
  6. 自旋鎖/非自旋鎖;
  7. 可中斷鎖/不可中斷鎖。

以上是常見的分類標準,下面我們來逐一介紹它們的含義。

偏向鎖/輕量級鎖/重量級鎖

第一種分類是偏向鎖/輕量級鎖/重量級鎖,這三種鎖特指 synchronized 鎖的狀態,通過在物件頭中的 mark word 來表明鎖的狀態。

偏向鎖

如果自始至終,對於這把鎖都不存在競爭,那麼其實就沒必要上鎖,只需要打個標記就行了,這就是偏向鎖的思想。一個物件被初始化後,還沒有任何執行緒來獲取它的鎖時,那麼它就是可偏向的,當有第一個執行緒來訪問它並嘗試獲取鎖的時候,它就將這個執行緒記錄下來,以後如果嘗試獲取鎖的執行緒正是偏向鎖的擁有者,就可以直接獲得鎖,開銷很小,效能最好。

輕量級鎖

JVM 開發者發現在很多情況下,synchronized 中的程式碼是被多個執行緒交替執行的,而不是同時執行的,也就是說並不存在實際的競爭,或者是隻有短時間的鎖競爭,用 CAS 就可以解決,這種情況下,用完全互斥的重量級鎖是沒必要的。輕量級鎖是指當鎖原來是偏向鎖的時候,被另一個執行緒訪問,說明存在競爭,那麼偏向鎖就會升級為輕量級鎖,執行緒會通過自旋的形式嘗試獲取鎖,而不會陷入阻塞。

重量級鎖

重量級鎖是互斥鎖,它是利用作業系統的同步機制實現的,所以開銷相對比較大。當多個執行緒直接有實際競爭,且鎖競爭時間長的時候,輕量級鎖不能滿足需求,鎖就會膨脹為重量級鎖。重量級鎖會讓其他申請卻拿不到鎖的執行緒進入阻塞狀態。

你可以發現鎖升級的路徑:無鎖→偏向鎖→輕量級鎖→重量級鎖

綜上所述,偏向鎖效能最好,可以避免執行 CAS 操作。而輕量級鎖利用自旋和 CAS 避免了重量級鎖帶來的執行緒阻塞和喚醒,效能中等。重量級鎖則會把獲取不到鎖的執行緒阻塞,效能最差。

可重入鎖/非可重入鎖

第 2 個分類是可重入鎖和非可重入鎖。可重入鎖指的是執行緒當前已經持有這把鎖了,能在不釋放這把鎖的情況下,再次獲取這把鎖。同理,不可重入鎖指的是雖然執行緒當前持有了這把鎖,但是如果想再次獲取這把鎖,也必須要先釋放鎖後才能再次嘗試獲取。

對於可重入鎖而言,最典型的就是 ReentrantLock 了,正如它的名字一樣,reentrant 的意思就是可重入,它也是 Lock 介面最主要的一個實現類。

共享鎖/獨佔鎖

第 3 種分類標準是共享鎖和獨佔鎖。共享鎖指的是我們同一把鎖可以被多個執行緒同時獲得,而獨佔鎖指的就是,這把鎖只能同時被一個執行緒獲得。我們的讀寫鎖,就最好地詮釋了共享鎖和獨佔鎖的理念。讀寫鎖中的讀鎖,是共享鎖,而寫鎖是獨佔鎖。讀鎖可以被同時讀,可以同時被多個執行緒持有,而寫鎖最多隻能同時被一個執行緒持有。

公平鎖/非公平鎖

第 4 種分類是公平鎖和非公平鎖。公平鎖的公平的含義在於如果執行緒現在拿不到這把鎖,那麼執行緒就都會進入等待,開始排隊,在等待佇列裡等待時間長的執行緒會優先拿到這把鎖,有先來先得的意思。而非公平鎖就不那麼“完美”了,它會在一定情況下,忽略掉已經在排隊的執行緒,發生插隊現象。

悲觀鎖/樂觀鎖

第 5 種分類是悲觀鎖,以及與它對應的樂觀鎖。悲觀鎖的概念是在獲取資源之前,必須先拿到鎖,以便達到“獨佔”的狀態,當前執行緒在操作資源的時候,其他執行緒由於不能拿到鎖,所以其他執行緒不能來影響我。而樂觀鎖恰恰相反,它並不要求在獲取資源前拿到鎖,也不會鎖住資源;相反,樂觀鎖利用 CAS 理念,在不獨佔資源的情況下,完成了對資源的修改。

自旋鎖/非自旋鎖

第 6 種分類是自旋鎖與非自旋鎖。自旋鎖的理念是如果執行緒現在拿不到鎖,並不直接陷入阻塞或者釋放 CPU 資源,而是開始利用迴圈,不停地嘗試獲取鎖,這個迴圈過程被形象地比喻為“自旋”,就像是執行緒在“自我旋轉”。相反,非自旋鎖的理念就是沒有自旋的過程,如果拿不到鎖就直接放棄,或者進行其他的處理邏輯,例如去排隊、陷入阻塞等。

可中斷鎖/不可中斷鎖

第 7 種分類是可中斷鎖和不可中斷鎖。在 Java 中,synchronized 關鍵字修飾的鎖代表的是不可中斷鎖,一旦執行緒申請了鎖,就沒有回頭路了,只能等到拿到鎖以後才能進行其他的邏輯處理。而我們的 ReentrantLock 是一種典型的可中斷鎖,例如使用 lockInterruptibly 方法在獲取鎖的過程中,突然不想獲取了,那麼也可以在中斷之後去做其他的事情,不需要一直傻等到獲取到鎖才離開。

好了,本課時的內容就全部講完了,下一課時我將會從悲觀鎖和樂觀鎖開始詳細講解這一系列的鎖的具體概念和特點,下一課時見。