最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 并發(fā)鎖ReentrantLock的實(shí)現(xiàn)

 更新時間:2026年04月23日 15:29:42   作者:暮年  
本文主要介紹了Java 并發(fā)鎖ReentrantLock的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

全路徑名:java.util.concurrent.locks.ReentrantLock 類定義如下:

/**
 * @since 1.5
 */
public class ReentrantLock implements Lock, java.io.Serializable {
    ...
}

ReentrantLock 類實(shí)現(xiàn)了 Lock 接口,JDK1.5 引入。

ReentrantLock 使用上分公平鎖和非公平鎖,兩種鎖機(jī)制。默認(rèn)無參構(gòu)造方法 ReentrantLock() 創(chuàng)建的是非公平鎖??梢允褂糜袇?gòu)造函數(shù) ReentrantLock(boolean fair) 選擇使用公平鎖,還是非公平鎖。具體實(shí)現(xiàn)是通過 ReentrantLock 的內(nèi)部類 FairSync 和 NonfairSync 來實(shí)現(xiàn)的。FairSync 和 NonfairSync 是 ReentrantLock 類中抽象內(nèi)部類 Sync 的子類。具體源碼如下:

public class ReentrantLock implements Lock, java.io.Serializable {
    ...
    private final Sync sync;
    ...
    abstract static class Sync extends AbstractQueuedSynchronizer {...}
    static final class NonfairSync extends Sync {...}
    static final class FairSync extends Sync {...}
    public ReentrantLock() {
        sync = new NonfairSync();
    }
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }
    public void lock() {
        sync.lock();
    }
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }
    public boolean tryLock() {
        return sync.nonfairTryAcquire(1);
    }
    public boolean tryLock(long timeout, TimeUnit unit)
            throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }
    public void unlock() {
        sync.release(1);
    }
    public Condition newCondition() {
        return sync.newCondition();
    }
    ...
}

java.util.concurrent.locks.Lock 接口定義了5個方法。具體源碼如下:

public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();
    Condition newCondition();
}

通過對 ReentrantLock 類 Lock 接口 lock() 方法的實(shí)現(xiàn), 來看 ReentrantLock 是如何實(shí)現(xiàn)公平鎖的。

先說方式,再看源碼更好理解一點(diǎn)。如果要公平,那就要有先來后到。就像超市購物結(jié)賬一樣:

  • 如果結(jié)賬時,恰好沒有人,那就直接結(jié)賬。直接就拿到了鎖。
  • 如果結(jié)賬時,已經(jīng)有人了,那就排到隊(duì)伍的后面,等到你的時候才可以結(jié)賬。也就是拿到了鎖。

ReentrantLock 內(nèi)部類 FairSync 負(fù)責(zé)實(shí)現(xiàn)公平鎖機(jī)制,F(xiàn)airSync 類繼承了 Sync 類,Sync類 繼承了 AbstractQueuedSynchronizer 類。下面是與 lock() 方法有個的源碼:

static final class FairSync extends Sync {

    final void lock() {
            acquire(1);
    }

    protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                    if (!hasQueuedPredecessors() &&
                            compareAndSetState(0, acquires)) {
                            setExclusiveOwnerThread(current);
                            return true;
                    }
            }
            else if (current == getExclusiveOwnerThread()) {
                    int nextc = c + acquires;
                    if (nextc < 0)
                            throw new Error("Maximum lock count exceeded");
                    setState(nextc);
                    return true;
            }
            return false;
    }
}
public abstract class AbstractQueuedSynchronizer
    extends AbstractOwnableSynchronizer
    implements java.io.Serializable {
    ...
    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }
    ...
    private Node addWaiter(Node mode) {
        Node node = new Node(Thread.currentThread(), mode);
        // Try the fast path of enq; backup to full enq on failure
        Node pred = tail;
        if (pred != null) {
            node.prev = pred;
            if (compareAndSetTail(pred, node)) {
                pred.next = node;
                return node;
            }
        }
        enq(node);
        return node;
    }
    ...
    final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
                }
                if (shouldParkAfterFailedAcquire(p, node) 
                        && parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }
}

FairSync 的 lock() 方法調(diào)用 AbstractQueuedSynchronizer 類 acquire() 方法獲取鎖。AbstractQueuedSynchronizer 類 acquire() 方法中,先使用 FairSync 類的 tryAcquire() 方法實(shí)現(xiàn)沒有人排隊(duì)的場景。

  • int c = getState(): 獲取的是 AbstractQueuedSynchronizer 類的一個狀態(tài)。c = 0 代表目前沒有線程拿到這個鎖
  • !hasQueuedPredecessors(): 沒有其他線程排隊(duì)
  • compareAndSetState(0, acquires):使用 CAS(Compare and Swap)CPU 硬件同步原語機(jī)制獲取鎖
  • setExclusiveOwnerThread(current):如果成功拿到鎖,將當(dāng)前線程和鎖綁定
  • else if (current == getExclusiveOwnerThread()) 如果鎖已經(jīng)被當(dāng)前線程綁定,狀態(tài) c 加 1。這塊就體現(xiàn)了 ReentrantLock 可重入的概念。同一個線程未釋放鎖的情況下可以重復(fù)拿到鎖,每次狀態(tài) c 加1。

AbstractQueuedSynchronizer 類 acquire() 方法中,如果沒人排隊(duì)的情況下,未能成功搶到鎖。那就進(jìn)入了排隊(duì)的場景:

  • for (;;) :無限循環(huán)
  • if (p == head && tryAcquire(arg)):只有排隊(duì)首的才有資格競爭鎖。p 是獲得鎖的線程
  • parkAndCheckInterrupt() 這個方法里實(shí)現(xiàn)的未獲得鎖的線程阻塞。這里不討論。

看完 ReentrantLock 公平鎖的實(shí)現(xiàn),非公平鎖的實(shí)現(xiàn)就簡單了。非公平鎖是通過 ReentrantLock 內(nèi)部類 實(shí)現(xiàn)的,源碼如下:

static final class NonfairSync extends Sync {
    final void lock() {
        if (compareAndSetState(0, 1))
            setExclusiveOwnerThread(Thread.currentThread());
        else
            acquire(1);
    }
    protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
    }
}
abstract static class Sync extends AbstractQueuedSynchronizer {
    ...
    final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
    }
    ...
}

從源碼看一看出,不排隊(duì),直接調(diào)用 compareAndSetState(0, 1) 方法搶。這就是非公平鎖。

到此這篇關(guān)于Java 并發(fā)鎖ReentrantLock的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java 并發(fā)鎖ReentrantLock內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

最新評論

桐乡市| 潼南县| 丰都县| 清远市| 黎川县| 四川省| 自治县| 皮山县| 巴中市| 柳江县| 南岸区| 稻城县| 绵竹市| 高密市| 全椒县| 新河县| 时尚| 临洮县| 雷波县| 平和县| 喀喇沁旗| 桃江县| 襄垣县| 台前县| 宁远县| 青河县| 准格尔旗| 崇信县| 偃师市| 迁安市| 南江县| 明光市| 宁强县| 嘉鱼县| 平乡县| 汽车| 桐城市| 若羌县| 洛隆县| 称多县| 吉林省|