【问题标题】:What did I wrong when I want to stop SwingWorker in this case?在这种情况下我想停止 SwingWorker 时我做错了什么?
【发布时间】:2019-03-19 18:00:10
【问题描述】:
public class Worker extends SwingWorker<Integer, String> {
private JLabel screen;

    public Worker(JLabel screen) {
        this.screen = screen;
    }

    @Override
    protected Integer doInBackground() throws Exception {
        for (; ; ) {
            publish(String.valueOf(Calendar.getInstance().getTimeInMillis()));
        }
    }

    @Override
    protected void process(List<String> chunks) {
        screen.setText(chunks.get(0));
    }
}

形式:

    public class Form extends JPanel{
    private JButton startButton;
    private JPanel rootPanel;
    private JButton stopButton;
    private JLabel screen;
    private Worker worker;

    public Form() {
        startButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                worker = new Worker(screen);
                worker.execute();
            }
        });
        stopButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                worker.cancel(true);
                System.out.println(worker.isDone());
                System.out.println(worker.isCancelled());
            }
        });
    }

    private void createUIComponents() {
        rootPanel = this;
    }
}

我尝试用 Tread 编写相同的代码,但它也不起作用。点击stopButton后控制台输出:

是的

是的

所以,工人已经完成了,但程序仍然继续显示毫秒。什么是死后生活?在使用 Thread 相同的情况下:方法 isAlive() 返回“false”。

【问题讨论】:

  • 您的循环永远不会终止,因此工作人员永远不会停止。代替for( ; ; )试试while (!Thread.interrupted())(发布方法不检查)
  • SwingWorker 应该调用 isCancelled() 方法来检测 worker 是否被取消,然后在 doInBackground() 方法中退出 while 循环。

标签: java multithreading swing swingworker


【解决方案1】:

根据您的代码,您似乎需要一个带有循环的工作线程来继续运行,直到主线程告诉它停止运行,这通过worker.cancel(true); 完成。问题是您正在取消它,但没有做任何事情来指示循环本身停止迭代。要解决此问题,您应该更改

for (; ; ) {
    publish(String.valueOf(Calendar.getInstance().getTimeInMillis()));
}

while(!isCancelled()){
    publish(String.valueOf(Calendar.getInstance().getTimeInMillis()));
}

注意 java 文档中“isCancelled”的措辞:

isCancelled()

如果此任务在正常完成之前被取消,则返回 true。 由于循环永远不会自行关闭,因此它永远不会正常完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    相关资源
    最近更新 更多