閱讀706 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Java鎖的種類以及辨析(三):阻塞鎖

鎖作為並發共享數據,保證一致性的工具,在JAVA平台有多種實現(如 synchronized 和 ReentrantLock等等 ) 。這些已經寫好提供的鎖為我們開發提供了便利,但是鎖的具體性質以及類型卻很少被提及。本係列文章將分析JAVA下常見的鎖名稱以及特性,為大家答疑解惑。

三、阻塞鎖:

阻塞鎖,與自旋鎖不同,改變了線程的運行狀態。
在JAVA環境中,線程Thread有如下幾個狀態:

1,新建狀態

2,就緒狀態

3,運行狀態

4,阻塞狀態

5,死亡狀態

阻塞鎖,可以說是讓線程進入阻塞狀態進行等待,當獲得相應的信號(喚醒,時間) 時,才可以進入線程的準備就緒狀態,準備就緒狀態的所有線程,通過競爭,進入運行狀態。
JAVA中,能夠進入\退出、阻塞狀態或包含阻塞鎖的方法有 ,synchronized 關鍵字(其中的重量鎖),ReentrantLock,Object.wait()\notify(),LockSupport.park()/unpart()(j.u.c經常使用)

下麵是一個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 isLocked;
    }

    @SuppressWarnings("unused")
    private volatile CLHNode                                            tail;
    private static final ThreadLocal<CLHNode>                           LOCAL   = new ThreadLocal<CLHNode>();
    private static final AtomicReferenceFieldUpdater<CLHLock1, CLHNode> UPDATER = AtomicReferenceFieldUpdater.newUpdater(CLHLock1.class,
                                                                                    CLHNode.class, "tail");

    public void 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占用率過高,但進入時間以及恢複時間都要比自旋鎖略慢。

在競爭激烈的情況下 阻塞鎖的性能要明顯高於 自旋鎖。

理想的情況則是; 在線程競爭不激烈的情況下,使用自旋鎖,競爭激烈的情況下使用,阻塞鎖。

最後更新:2017-05-23 16:32:38

  上一篇:go  智能哲學:“第三問題”與圖靈的“模仿遊戲”
  下一篇:go  《迷人的8051單片機》----第1章 繽紛電世界 1.1電路中的秘密