Java SwingWorker取消合作吗?

时间:2014-12-05 05:56:40

标签: java multithreading swingworker

非常感谢您理解这一点。我的理解是取消SwingWorker线程是合作的。然而,这不是我所看到的。

我有下面的代码将停止SwingWorker线程,即使我没有可中断的操作。我不希望它以这种方式工作。注意我在doStuff()中特别设置了一个无限循环的测试。当我在main()例程中取消时:

worker.cancel(真),

我最终在done()函数中指示doInBackground()已退出(特别是在Exception处理程序中)。看起来即使在没有可中断操作的情况下线程也被杀死了。请注意,如果我更改为worker.cancel(false),我会得到相同的效果。

class AWorker extends SwingWorker<String, Object> {
    void doStuff() {
        System.out.println("Entered doStuff");    
        while (true);
    }

    @Override
    public String doInBackground() {
        //System.out.println("doInBackground started");
        doStuff();
        return "hello";
    }

    @Override
    protected void done() {
        try {
            System.out.println("done() entered");
            String status = get();
            System.out.println("done(): get = " + status);
        } catch (Exception e) {
            System.out.println("done(): Exception: " + e);
        }
    }

    public static void main(String[] args) throws Exception {
        AWorker worker = new AWorker();
        worker.execute();

        Thread.sleep(5000);
        worker.cancel(true);

    }
}

我应该补充一点,我可以完全按照Java文档中的描述,通过合作放入一个在我取消或通过轮询isCancelled()时被中断的睡眠。只是想知道为什么它在上面的代码片段中做了它。如果我冒险猜测,看起来当我在没有刚刚描述的协作机制的情况下调用worker.cancel()时,会立即调用done()函数。

1 个答案:

答案 0 :(得分:0)

SwingWorker.done()方法的文档似乎有点不对劲。它表示在doInBackground方法完成后## 34;调用了done()&#34;但是,首先,当您取消SwingWorker时,即使您从未启动过,也显然会调用done()。其次,如果取消SwingWorker,则立即调用done(),即使doInBackground()方法尚未返回。这就是这里发生的事情。

调用done()时,无限循环仍在运行。我确认使用以下代码将所有线程堆栈跟踪转储到控制台:

static void dumpThreads() {
    for (java.util.Map.Entry<Thread,StackTraceElement[]> t : Thread.getAllStackTraces().entrySet()) {
        System.out.println(t.getKey() + ":");
        for (StackTraceElement e : t.getValue()) {
            System.out.println("    " + e);
        }
    }
}

我在done()中插入了对该方法的调用。其中一个线程堆栈跟踪显示无限循环在那时仍然存在并且很好:

Thread[SwingWorker-pool-1-thread-1,5,main]:
    AWorker.doStuff(AWorker.java:8)
    AWorker.doInBackground(AWorker.java:14)
    javax.swing.SwingWorker$1.call(SwingWorker.java:295)
    java.util.concurrent.FutureTask.run(FutureTask.java:266)
    javax.swing.SwingWorker.run(SwingWorker.java:334)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    java.lang.Thread.run(Thread.java:744)

但是,无限循环确实在之后不久被强制停止,而不是由SwingWorker,而是在程序结束时,因为当没有非守护进程线程运行时(SwingWorker线程是守护进程线程)并且没有创建窗口,程序退出。这两件事的组合(狡猾的文档和自动退出)给出了取消SwingWorker神奇地停止任务的外观,但它不是。

如果从main方法打开一个窗口,将阻止程序自动退出。然后,您将从系统任务管理器中看到程序保持运行(并在该无限循环中继续占用CPU),直到您终止它为止。

简而言之,是的,SwingWorker取消 合作。