java - SwingWorker:何时调用 done 方法?

标签 java swing swingworker cancellation

SwingWorker 的 done() 方法的 Javadoc:

Executed on the Event Dispatch Thread after the doInBackground method is finished.

我有线索表明,在取消 worker 的情况下,情况并非如此。
Done 在每种情况下都被调用(正常终止或取消),但是当 cancelled不入队到 EDT,因为它发生在正常终止.

SwingWorker 被取消的情况下,何时调用 done 是否有更精确的分析?

澄清: 这个问题是关于如何cancel SwingWorkerNOT。这里假设 SwingWorker 以正确的方式取消。
不是关于线程在应该完成时仍在工作的情况。

最佳答案

当一个线程被取消时

myWorkerThread.cancel(true/false);

done 方法(非常令人惊讶)由 cancel 方法本身调用。

您可能期望发生的事情,但实际上并没有:
- 您调用取消(使用 mayInterrupt 或不使用)
--cancel 设置线程取消
- doInBackground 退出
- 完成被称为*
(* done 被 enqueued 到 EDT,这意味着,如果 EDT 很忙,它会在 EDT 完成它正在做的事情之后发生)

实际发生了什么:
- 你调用取消(无论是否使用 mayInterrupt)
--cancel 设置线程取消
- done 被作为取消代码的一部分调用*
- doInBackground 将在完成循环后退出
(*done 不会加入 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!");}

}

}

关于java - SwingWorker:何时调用 done 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6204141/

相关文章:

java - 如果两个组件大小相同且全屏,JLayeredPane 不会绘制低组件

java - Hibernate:如何在Hibernate中删除多行?

java - jxmultisplitpane:如何使用?

java - 使用 jFreeChart 的多个图形中的多个图形

java - 使用java作为输入参数类的工厂模式

java - 如何处理 VoIP 的音频流和混合

java - 如何对齐两个JButton以使其右对齐?

Java:完全禁用任何 Swing 不需要的蜂鸣声的方法?

java - 我在制作Java版记事本时遇到问题

java - 我如何使 JLabel 文本自动更改?