在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/Java/ 關(guān)于ReentrantLock的lock()方法的一個疑問

關(guān)于ReentrantLock的lock()方法的一個疑問

公平鎖和非公平鎖在嘗試獲取鎖失敗!tryAcquire(arg)后,會調(diào)用acquireQueued(addWaiter(Node.EXCLUSIVE), arg)方法,方法源碼如下:

圖片描述

為什么這里p==head的時候才會再次嘗試獲取鎖?對于非公平鎖,競爭鎖是不依賴排隊順序的,不是應(yīng)該不管前驅(qū)結(jié)點是否是head,都應(yīng)該再次去嘗試獲取鎖嗎?

回答
編輯回答
解夏

在同步器中的節(jié)點,始終是有順序的。非公平指的是沒有進入同步隊列的線程與首節(jié)點的后繼節(jié)點中的線程非公平,也有可能是首節(jié)點中的線程和首節(jié)點后繼節(jié)點中的線程非公平競爭,比如首節(jié)點中的線程釋放鎖后又立即去獲取鎖。
體現(xiàn)在ReentrantLock代碼中話,就是NonfairSynctryAcquire實現(xiàn)和FairSynctryAcquire實現(xiàn)是不一樣的。

static final class NonfairSync extends Sync {
        。。。。。。
        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }
        。。。。
}
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;
}
static final class FairSync extends Sync {
        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 final boolean hasQueuedPredecessors() {
        // The correctness of this depends on head being initialized
        // before tail and on head.next being accurate if the current
        // thread is first in queue.
        Node t = tail; // Read fields in reverse initialization order
        Node h = head;
        Node s;
        return h != t &&
            ((s = h.next) == null || s.thread != Thread.currentThread());
}

FairSynctryAcquire方法,多了一個!hasQueuedPredecessors()判斷。如果同步隊列為空,或者只有首節(jié)點,或者首節(jié)點的后繼節(jié)點中的線程是當(dāng)前線程,那么hasQueuedPredecessors()false,!hasQueuedPredecessors()為true,調(diào)用tryAcquire的當(dāng)前線程就可以去獲取同步狀態(tài)。

2018年9月20日 16:27