ReentrantLock原始碼之公平鎖的實現
阿新 • • 發佈:2022-05-14
- 程式碼案例
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());
}