当一个线程被取消时
myWorkerThread.cancel(true/false);
done 方法(非常令人惊讶)由 cancel 方法本身调用。
您可能期望发生的事情,但实际上没有:
-您调用取消(使用 mayInterrupt 或不使用)
-取消设置线程取消
-doInBackground 退出
-调用完成*
(* 完成排队到 EDT ,这意味着,如果 EDT 很忙,它会在 EDT 完成它正在做的事情之后发生)
实际发生了什么:
- 您调用取消(使用 mayInterrupt 或不使用)
- 取消设置线程取消
- 完成作为取消代码的一部分调用*
- doInBackground 将在完成其循环时退出
(*完成没有加入 EDT,而是调用到取消调用中,因此它对 EDT 有非常直接的影响,通常是 GUI)
我提供了一个简单的例子来证明这一点。
复制、粘贴和运行。
1.我在done里面生成了一个运行时异常。堆栈线程显示完成是由取消调用的。
2. 取消后大约 4 秒后,你会收到来自 doInBackground 的问候,这进一步证明在线程退出之前调用了 done。
import java.awt.EventQueue;
import javax.swing.SwingWorker;
public class SwingWorker05 {
public static void main(String [] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
W w = new W();
w.execute();
Thread.sleep(1000);
try{w.cancel(false);}catch (RuntimeException rte) {
rte.printStackTrace();
}
Thread.sleep(6000);
} catch (InterruptedException ignored_in_testing) {}
}
});
}
public static class W extends SwingWorker <Void, Void> {
@Override
protected Void doInBackground() throws Exception {
while (!isCancelled()) {
Thread.sleep(5000);
}
System.out.println("I'm still alive");
return null;
}
@Override
protected void done() {throw new RuntimeException("I want to produce a stack trace!");}
}
}