話說 ReentrantLock_源碼

以前文章寫AQS的時候有說過公平鎖的代碼 這裏以非公平鎖來看一下java

面試的時候設計模式:模板方法 在AQS裏體現的淋漓盡致 ,你要是從設計模式扯到這裏,而後你正好又看過AQS在ReentrantLock中的實現,那你就能夠讓面試官眼前一亮面試

Lock lock  =  new ReentrantLock(false);
lock.lock();

/**
     * 申請鎖
     *
     * <p>Acquires the lock if it is not held by another thread and returns
     * immediately, setting the lock hold count to one.
     *  若是沒有其餘線程持有這個鎖,就立刻返回,並設置鎖持有數爲1
     * <p>If the current thread already holds the lock then the hold
     * count is incremented by one and the method returns immediately.
     * 若是當前線程持有鎖,就吧持有數量+1(可重入) 而後當即返回 
     * <p>If the lock is held by another thread then the
     * current thread becomes disabled for thread scheduling
     * purposes and lies dormant until the lock has been acquired,
     * at which time the lock hold count is set to one.
     * 若是鎖被其餘線程持有,當前線程對於調度就不可用,而後睡着, 直到獲取鎖,而後把鎖持有數改成1 
     */
// ReentrantLock.class
public void lock() {
    sync.lock();
}
// NonfairSync.class
final void lock() {
    // 先搶一下(上一篇說的 :小強二話不說先看看能不能跟老闆選餅)
    if (compareAndSetState(0, 1))
        setExclusiveOwnerThread(Thread.currentThread());
    else
        // 若是沒有搶到 再去申請
        acquire(1);
}
// AbstractQueuedSynchronizer.class
 public final void acquire(int arg) {
        // 這個tryAcquire會再搶一次(小強還抱着插隊的幻想)
        if (!tryAcquire(arg) &&
            // 搶不到 就後邊排隊吧
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
 }

 // ReentrantLock.class
 protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
 }

// ReentrantLock.class 
// 這裏須要瞭解AQS 我其餘文章有寫 能夠去看
final boolean nonfairTryAcquire(int acquires) {
    // 獲取當前線程
    final Thread current = Thread.currentThread();
    // 獲取state標誌位
    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;
}

image

有問題能夠留言哦,也能夠公衆號留言(回覆快):設計模式

相關文章
相關標籤/搜索