線程中斷是協作式機制:interrupt() 僅發出請求,目標線程需在合適時機自行響應並退出。本文講解兩種標準處理模式,並給出「限時運行任務」實戰範例。
InterruptedException 後在方法簽名上拋出,調用者決定如何處理。Thread.currentThread().interrupt() 重置標誌位,保證上層代碼仍能感知中斷。需求:在指定超時內執行任務,無論任務是否響應中斷,超時即強制返回結果或異常。
public class TimeCount {
private static final ScheduledExecutorService cancelExec = Executors.newSingleThreadScheduledExecutor();
public static void timedRun(final Runnable r, long timeout, TimeUnit unit) throws Throwable {
class RethrowableTask implements Runnable {
private volatile Throwable t;
public void run() {
try { r.run(); } catch (Throwable e) { this.t = e; }
}
void rethrow() throws Throwable { if (t != null) throw t; }
}
RethrowableTask task = new RethrowableTask();
final Thread taskThread = new Thread(task);
taskThread.start();
// 超時中斷
cancelExec.schedule(() -> taskThread.interrupt(), timeout, unit);
// 等待任務結束,最多等待超時時間
taskThread.join(unit.toMillis(timeout));
// 拋出任務異常或正常返回
task.rethrow();
}
}
ScheduledExecutorService 替代舊版 Timer,支援線程池、異常處理更健壯。join(timeout) 確保主線程不會無限阻塞,超時即繼續執行。volatile Throwable t 保證異常跨線程可見性。InterruptedException 拋出點),超時後仍會因 join 返回而繼續,調用者可選擇記錄日誌、補償邏輯等。sleep、wait、BlockingQueue)天然響應中斷,拋出 InterruptedException。Thread.interrupted() 並拋出異常或返回。InterruptedException 後不要吞掉,必須傳遞或恢復中斷狀態。掌握中斷協作模式,是編寫可靠、可取消、可超時控制的並發程序基石。