java - 在这种情况下我想停止 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”。
解决方案
根据您的代码,您似乎需要一个带有循环的工作线程来继续运行,直到主线程告诉它停止运行,这通过worker.cancel(true);
. 问题是您正在取消它,但没有做任何事情来指示循环本身停止迭代。要解决此问题,您应该更改
for (; ; ) {
publish(String.valueOf(Calendar.getInstance().getTimeInMillis()));
}
至
while(!isCancelled()){
publish(String.valueOf(Calendar.getInstance().getTimeInMillis()));
}
请注意 java 文档中“isCancelled”的措辞:
isCancelled()
如果此任务在正常完成之前被取消,则返回 true。由于循环永远不会自行关闭,因此它永远不会正常完成。
推荐阅读
- python - 正则表达式检测电话号码
- swift - Swift:iBeacon 在 iOS 结束进程之前运行代码
- javascript - Vue.js 无法向 $root 元素发出事件
- c# - 即使在添加清单并提供权限后,MediaCapture 初始化也会失败
- excel - 需要比较两列并将输出提供给第三列
- c# - 如何在 Google Or-Tools 中限制路线持续时间?
- c# - 我能够从 ALM 获取文件夹,但不能从测试中获取 - c#
- gradle - 如何在具有不同名称和路径的自定义任务中创建多个 jar
- ios - UIButton 在 iOS 13 中作为 UITableViewCell 的辅助视图的位置错误
- html - 如何删除 MDBootstrap 类默认选择颜色