【发布时间】:2013-09-13 04:56:32
【问题描述】:
我有一段JFrame 代码,它在关闭时停止SwingWorker:
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.SwingWorker;
import javax.swing.WindowConstants;
/**
*
* @author yccheok
*/
public class JavaApplication11 extends JFrame {
public JavaApplication11() {
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
final Task task = new Task();
task.execute();
addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
if (task != null) {
task.cancel(true);
}
}
});
}
public class Task extends SwingWorker<Void, Void> {
@Override
protected Void doInBackground() {
for (int i = 0; i < 1000; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println("interrupted in doInBackground");
break;
}
System.out.println("-> " + i);
}
return null;
}
@Override
public void done() {
System.out.println("DONE!!!");
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new JavaApplication11().setVisible(true);
}
}
但是,随机地,当我关闭JFrame 时,我意识到SwingWorker 的done 方法在doInBackground 完成之前执行。 (你需要多次执行上面的JFrame才能产生问题)
-> 0
-> 1
-> 2
-> 3
-> 4
DONE!!!
interrupted in doInBackground
我可以知道为什么会这样吗?
【问题讨论】:
-
这可能是标准输出竞争条件的演示
-
如果 MadProgrammer 是正确的,包括在您的 sysout 调用上的时间戳应该会显示它... 跟踪此问题的一种策略是在您的 IDE 中包含 Swingworker 的源代码,并在完成和doInBackgroun的最后一步......只是一个想法......
-
难道不是因为在 EDT 上调用了 done 并且 doInBackground 在自己的线程上运行,所以它们不必一个接一个地来?并自动取消呼叫完成。另外,只需在打印之前在 catch 块中添加另一个 sleep ,您每次都会看到它。
-
IF 我明白发生了什么。支持
SwingWorker的Future被取消,done方法在同一Thread的上下文中被调用。这意味着done可能在doInBackground方法正在运行的Thread被调度运行并检测到中断之前执行...
标签: java multithreading swing swingworker