首页 > 解决方案 > 在这种情况下我想停止 SwingWorker 时我做错了什么?

问题描述

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 编写相同的代码,但它也不起作用。单击停止按钮后的控制台输出:

真的

真的

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

标签: javamultithreadingswingswingworker

解决方案


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

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

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

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

isCancelled()

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


推荐阅读