1. 程式人生 > 其它 >ReentrantLock原始碼之公平鎖的實現

ReentrantLock原始碼之公平鎖的實現

  • 程式碼案例
public class ReentrantLockDemo {

    public static void main(String[] args) {
        ReentrantLock reentrantLock = new ReentrantLock(true);
        reentrantLock.lock();
        reentrantLock.unlock();
    }

}
  • 檢視無參構造方法
    public ReentrantLock() {
        sync = new NonfairSync();    // new了1個非公平實現
    }
  • 檢視sync

  • 檢視有參構造

    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();    // 為true時返回公平實現,否則返回非公平實現
    }
  • ReentrantLock實現了Lock介面

  • 檢視方法

  • 檢視內部類

  • 檢視lock方法

public class ReentrantLockDemo {

    public static void main(String[] args) {
        ReentrantLock reentrantLock = new ReentrantLock(true);
        reentrantLock.lock();
        reentrantLock.unlock();
    }

}

public void lock() {
    sync.acquire(1);
}

public final void acquire(int arg) {
    // 嘗試獲取鎖
    if (!tryAcquire(arg) &&
        acquireQueued(addWaiter(Node.EXCLUSIVE), arg))    // 同時獲取佇列失敗
        selfInterrupt();      // 則執行緒終止
}
  • 檢視嘗試獲取鎖的方法
    protected boolean tryAcquire(int arg) {
        throw new UnsupportedOperationException();
    }
  • 檢視非公平實現
static final class NonfairSync extends Sync {
    private static final long serialVersionUID = 7316153563782823691L;
    protected final boolean tryAcquire(int acquires) {
        return nonfairTryAcquire(acquires);
    }
}

@ReservedStackAccess
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;    // 重入狀態加1
        if (nextc < 0) // overflow      // 超過最大重入狀態,丟擲異常
            throw new Error("Maximum lock count exceeded");
        setState(nextc);    // 更新
        return true;    // 獲得鎖
    }
    return false;
}
  • 檢視addWaiter方法
    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }
  • 檢視EXCLUSIVE

  • 檢視addWaiter方法

    private Node addWaiter(Node mode) {
        Node node = new Node(mode);    // 傳入引數,當前執行緒,new1個Node

        for (;;) {
            Node oldTail = tail;    // 前置節點指向尾節點
            if (oldTail != null) {
                node.setPrevRelaxed(oldTail);
                if (compareAndSetTail(oldTail, node)) {    // node設定為尾節點
                    oldTail.next = node;
                    return node;
                }
            } else {
                initializeSyncQueue();    // 若整條佇列為null,執行入隊
            }
        }
    }
  • 檢視Node
Node(Node nextWaiter) {
    this.nextWaiter = nextWaiter;
    THREAD.set(this, Thread.currentThread());
}