### 中斷恢復后的執行流程
喚醒后,會執行return Thread.interrupted();,這個函數返回的是當前執行線程的中斷狀態,并清除。
~~~
// java.util.concurrent.locks.AbstractQueuedSynchronizer
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);
return Thread.interrupted();
}
~~~
再回到acquireQueued代碼,當parkAndCheckInterrupt返回True或者False的時候,interrupted的值不同,但都會執行下次循環。如果這個時候獲取鎖成功,就會把當前interrupted返回。
~~~
// java.util.concurrent.locks.AbstractQueuedSynchronizer
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
~~~
如果acquireQueued為True,就會執行selfInterrupt方法。
~~~
// java.util.concurrent.locks.AbstractQueuedSynchronizer
static void selfInterrupt() {
Thread.currentThread().interrupt();
}
~~~
該方法其實是為了中斷線程。但為什么獲取了鎖以后還要中斷線程呢?這部分屬于Java提供的協作式中斷知識內容,感興趣同學可以查閱一下。這里簡單介紹一下:
1. 當中斷線程被喚醒時,并不知道被喚醒的原因,可能是當前線程在等待中被中斷,也可能是釋放了鎖以后被喚醒。因此我們通過Thread.interrupted()方法檢查中斷標記(該方法返回了當前線程的中斷狀態,并將當前線程的中斷標識設置為False),并記錄下來,如果發現該線程被中斷過,就再中斷一次。
2. 線程在等待資源的過程中被喚醒,喚醒后還是會不斷地去嘗試獲取鎖,直到搶到鎖為止。也就是說,在整個流程中,并不響應中斷,只是記錄中斷記錄。最后搶到鎖返回了,那么如果被中斷過的話,就需要補充一次中斷。
這里的處理方式主要是運用線程池中基本運作單元Worder中的runWorker,通過Thread.interrupted()進行額外的判斷處理,感興趣的同學可以看下ThreadPoolExecutor源碼
- 簡介
- 概述
- 進程vs線程
- 資源限制
- 有關并行的兩個定律
- 線程同步和阻塞
- 線程阻塞
- 線程的特性
- 守護線程
- 線程異常
- Thread
- 線程狀態
- 線程中斷
- wait¬ify
- suspend&resume
- join&yield
- notify¬ifyAll
- Thread.sleep
- 線程任務
- Runnable
- Callable
- Future模式
- FutureTask
- 線程實現方式
- 內核線程實現
- 用戶線程實現
- 混合實現
- Java線程的實現
- java與協程
- 纖程-Fiber
- 線程調度
- 多線程協作方式
- 阻塞
- 放棄
- 休眠
- 連接線程
- 線程估算公式
- 線程活躍性
- 死鎖
- 線程安全性
- 對象的發布與逸出
- 構造方法溢出
- 線程封閉
- 對象的可變性
- 原子性
- 原子操作
- CPU原子操作原理
- 總線鎖
- 緩存鎖
- JAVA如何實現原子操作
- long和double讀寫操作原子性
- Adder和Accumulator
- 線程性能
- 同步工具類
- 閉鎖
- CountDownLatch
- FutureTask
- 信號量
- 柵欄
- CyclicBarrier
- Exchanger
- 并發編程
- volatile
- synchronized
- 無鎖
- 偏向鎖
- 輕量級鎖
- 鎖的優缺點對比
- 鎖升級
- 鎖消除
- Monitor
- synchronized語法
- Mutex Lock
- synchronized實踐問題
- synchronized&ReentrantLock
- Lock
- ReentrantLock
- Condition
- 讀寫鎖
- ReadWriteLock
- StampedLock
- 線程池
- Executor
- ExecutorService
- Executors
- ThreadPoolExecutor
- RejectedExecutionHandler
- ThreadFactory
- 線程池大小公式
- 動態調整線程池大小
- Fork/Join框架
- ForkJoinPool
- CompletableFuture
- JUC并發工具包
- LockSupport
- 延時任務與周期任務
- Timer
- TimerTask
- 異構任務并行化
- CompletionService
- volatile和synchronized比較
- 鎖優化
- 鎖相關概念
- 悲觀鎖(排它鎖)
- 樂觀鎖
- 自旋鎖
- 樂觀鎖vs悲觀鎖
- JVM鎖優化-鎖消除
- ThreadLocal
- InheritableThreadLocal
- TransmittableThreadLocal
- ThreadLocalRandom
- 無鎖
- AtomicInteger
- Unsafe
- AtomicReference
- AtomicStampedReference
- AtomicIntegerArray
- AtomicIntegerFieldUpdater
- 無鎖Vector
- LongAdder
- LongAccumulator
- 常見鎖類型
- 悲觀鎖&獨占鎖
- 樂觀鎖
- 樂觀鎖vs悲觀鎖
- 自旋鎖vs適應性自旋鎖
- 公平鎖vs非公平鎖
- 可重入鎖vs非可重入鎖
- 獨享鎖vs共享鎖
- 互斥鎖
- CAS
- AQS介紹
- AQS深入剖析
- AQS框架
- AQS核心思想
- AQS數據結構
- 同步狀態State
- ReentrantLock vs AQS
- AQS與ReentrantLock的關聯
- ReentrantLock具體實現
- 線程加入等待隊列
- 等待隊列中線程出隊列時機
- 如何解鎖
- 中斷恢復后的執行流程
- ReentrantLock的可重入應用
- JUC中的應用場景
- 自定義同步工具
- CLH鎖
- 并發框架
- Akka
- Disruptor-無鎖緩存框架
- 常見面試題
- 兩個線程交替打印A和B
- 附錄