鎖作為並發共享數據,保證一致性的工具,在JAVA平台有多種實現(如synchronized 和ReentrantLock等等) 。這些已經寫好提供的鎖為我們開發提供了便利,但是鎖的具體性質以及類型卻很少被提及。本系列文章將分析JAVA下常見的鎖名稱以及特性,為大家答疑解惑。
阻塞鎖
阻塞鎖,與自旋鎖不同,改變了執行緒的運作狀態。
在JAVA環境中,執行緒Thread有以下幾個狀態:
1,新建狀態
2,就緒狀態
3,運行狀態
4,阻塞狀態
5,死亡狀態
阻塞鎖,可以說是讓線程進入阻塞狀態進行等待,當獲得相應的信號(喚醒,時間) 時,才可以進入線程的準備就緒狀態,準備就緒狀態的所有線程,通過競爭,進入運行狀態。
JAVA中,能夠進入/退出、阻塞狀態或包含阻塞鎖的方法有,synchronized 關鍵字(其中的重量鎖),ReentrantLock,Object.wait()/notify(),LockSupport.park()/unpart()( juc經常使用)
下面是一個JAVA 阻塞鎖定實例:
package lock;import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;import java.util.concurrent.locks.LockSupport;public class CLHLock1 { public static class CLHNode { private volatile Thread isLock 。 lock() { CLHNode node = new CLHNode(); LOCAL.set(node); CLHNode preNode = UPDATER.getAndSet(this, node); if (preNode != null) { preNode.isLocked = Thread.currentThread(); LockSupport .park(this); preNode = null; LOCAL.set(node); } } public void unlock() { CLHNode node = LOCAL.get(); if (!UPDATER.compareAndSet(this, node, null)) { System.out.println("unlock/t" + node.isLocked.getName()); LockSupport.unpark(node .isLocked); } node = null; }}
這裡我們使用了LockSupport.unpark()的阻塞鎖。 此例子是將CLH鎖修改而成。
阻塞鎖的優點在於,阻塞的執行緒不會佔用cpu時間,不會導致CPu佔用率過高,但進入時間以及恢復時間都要比自旋鎖略慢。
在競爭激烈的情況下阻塞鎖的性能要明顯高於自旋鎖。
理想的情況則是; 在線程競爭不激烈的情況下,使用自旋鎖,競爭激烈的情況下使用,阻塞鎖。
(全文完)