java併發編程學習之再談公平鎖和非公平鎖

java併發編程學習之顯示鎖Lock裏有提過公平鎖和非公平鎖,咱們知道他的使用方式,以及非公平鎖的性能較高,在AQS源碼分析的基礎上,咱們看看NonfairSync和FairSync的區別在什麼地方。java

lock方法

//非公平鎖NonfairSync
final void lock() {
    if (compareAndSetState(0, 1))
        setExclusiveOwnerThread(Thread.currentThread());
    else
        acquire(1);
}
//公平鎖FairSync
final void lock() {
    acquire(1);
}

從源碼能夠看出,獲取鎖的時候,非公平鎖會先嚐試獲取,獲取不到再調用acquire方法,而公平鎖直接調用acquire方法。編程

tryAcquire方法

////非公平鎖NonfairSync
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;
}
////公平鎖FairSync
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;
}

從源碼能夠看出,公平鎖再嘗試獲取鎖的時候,先判斷隊列是否有其餘節點在等待,沒有再獲取。而非公平鎖直接嘗試獲取鎖。segmentfault

相關文章
相關標籤/搜索