[英]How can I interrupt a thread/future/executor with reason in Java?
我想知道為什么給定線程被中斷。 它是否被我(我的代碼的一部分)、其他庫或任何其他原因打斷了?
現在我可以通過
Thread.interrupt()
取消未來
Future.cancel(boolean mayInterruptIfRunning)
通過以下方式關閉 Executor
ExecutorService.shutdown() or ExecutorService.shutdownNow()
但是,他們都沒有給我發送原因的選項(執行中斷的信息)。 換句話說,我不能用更詳細的消息或原因拋出和捕獲 InterruptedException。
編輯:基於 Glains 解決方案,我准備了一個類似的解決方案,但使用了 Callable
public class MyCallable<T> implements Callable<T> {
private final Callable<T> callable;
private volatile Thread thread;
private volatile String interruptReason;
public MyCallable(final Callable<T> callable) {
this.callable = callable;
this.thread = null;
}
@Override
public T call() throws Exception {
this.thread = Thread.currentThread(); // not getCurrentThread()
try {
return callable.call();
}
catch (InterruptedException e) {
System.out.println("Thread is interrupted: " + this.interruptReason);
}
}
public void interrupt(String interruptReason) {
this.interruptReason = interruptReason;
thread.interrupt();
}
}
為此,您必須編寫自定義 API,因為無法以特定原因中止Thread
。 要使Runnable
能夠被中斷,您可以創建一個提供此功能的自定義接口:
public interface Interruptable {
default void interrupt() {
interrupt(Reason.unknown());
}
void interrupt(Reason reason);
}
定義的原因可以是任何東西,但以下可能適合您的用例:
public class Reason {
public static Reason unknown() {
return new Reason("unknown");
}
private final String reason;
public Reason(String reason) {
this.reason = reason;
}
public String getReason() {
return reason;
}
}
現在,您將不得不調整您的Runnable
實現,以便它可以被中斷。 請注意,以下解決方案優雅地中斷了線程,這意味着當前迭代將完成,但不會開始新的迭代。 如果要真正中斷線程,則需要存儲對執行Runnable
實例run
方法的線程的引用,因為不會從同一線程調用interrupt
方法。 然后您可以在該引用上調用Thread.interrupt
。
public class MyRunnable implements Runnable, Interruptable {
private final AtomicBoolean running = new AtomicBoolean(false);
@Override
public void interrupt(Reason reason) {
running.set(false);
System.out.println("Thread is interrupted: " + reason.getReason());
}
@Override
public void run() {
running.set(true);
while (running.get()) {
// do work
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.