文章目錄
- 1. 概述
- 2. 回應中斷的原理
- 2.1 cancelAcquire
1. 概述
AQS和ReentrantLock可以回應中斷嗎?
是的,可以,但是要通過lockInterruptibly()實作,如果呼叫的是 lock(),則不可以,
2. 回應中斷的原理
ReentrantLock回應中斷的原理也很簡單,我們知道ReentrantLock的阻塞原理就是呼叫了LockSupport 的park(Object blocker)方法,該方法可以回應中斷,

詳情可參見《LockSupport 阻塞和中斷》
lockInterruptibly()在收到LockSupport 的回應中斷后,會拋出例外,然后重置阻塞節點的waitstatus標識為1,標識CANCELLED,

注意:最侄訓往上層拋出該例外
2.1 cancelAcquire
標記當前節點為Node.CANCELLED,并且嘗試洗掉無效節點:
private void cancelAcquire(Node node) {
// Ignore if node doesn't exist
if (node == null)
return;
//1. node不再關聯到任何執行緒
node.thread = null;
//2. 跳過被cancel的前繼node,找到一個有效的前繼節點pred
// Skip cancelled predecessors
Node pred = node.prev;
while (pred.waitStatus > 0)
node.prev = pred = pred.prev;
// predNext is the apparent node to unsplice. CASes below will
// fail if not, in which case, we lost race vs another cancel
// or signal, so no further action is necessary.
Node predNext = pred.next;
//3. 將node的waitStatus置為CANCELLED
// Can use unconditional write instead of CAS here.
// After this atomic step, other Nodes can skip past us.
// Before, we are free of interference from other threads.
node.waitStatus = Node.CANCELLED;
//4. 如果node是tail,更新tail為pred,并使pred.next指向null
// If we are the tail, remove ourselves.
if (node == tail && compareAndSetTail(node, pred)) {
compareAndSetNext(pred, predNext, null);
} else {
// If successor needs signal, try to set pred's next-link
// so it will get one. Otherwise wake it up to propagate.
//
int ws;
//5. 如果node既不是tail,又不是head的后繼節點
//則將node的前繼節點的waitStatus置為SIGNAL
//并使node的前繼節點指向node的后繼節點
if (pred != head &&
((ws = pred.waitStatus) == Node.SIGNAL ||
(ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
pred.thread != null) {
Node next = node.next;
if (next != null && next.waitStatus <= 0)
compareAndSetNext(pred, predNext, next);
} else {
//6. 如果node是head的后繼節點,則直接喚醒node的后繼節點
unparkSuccessor(node);
}
node.next = node; // help GC
}
}

參考:
《Java AbstractQueuedSynchronizer原始碼閱讀3-cancelAcquire()》
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/258783.html
標籤:區塊鏈
上一篇:C/C++陣列與指標
