我们正在使用 Foxtrot 包来停止卡住 swing 应用程序。
但是在下面的代码中它会造成死锁。
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import foxtrot.Task;
import foxtrot.Worker;
public class FoxtrotExample extends JFrame {
public static void main(String[] args) {
FoxtrotExample example = new FoxtrotExample();
example.setVisible(true);
}
boolean st = true;
public FoxtrotExample() {
super("Foxtrot Example");
final JButton button = new JButton("Take a nap !");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Start..");
button.setText("Sleeping...");
String text = null;
try {
text = (String) Worker.post(new Task() {
public Object run() throws Exception {
System.out.println("Inside Worker 1");
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
System.out.println("Inside invokeLater");
Worker.post(new Task() {
@Override
public Object run()
throws Exception {
System.out.println("Inside Worker 2");
st = false;
return null;
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
});
while (st) {
System.out.println("Inside the loop..");
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
return "Slept !";
}
});
} catch (Exception x) {
}
button.setText(text);
System.out.println("Finished.....");
}
});
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
Container c = getContentPane();
c.setLayout(new GridBagLayout());
c.add(button);
setSize(300, 200);
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
Dimension size = getSize();
int x = (screen.width - size.width) >> 1;
int y = (screen.height - size.height) >> 1;
setLocation(x, y);
}
}
如果使用 ConcurrentWorker 这会工作得很好。任何人都可以解释一下这一点。 我有点困惑 EDT 在这里的表现?
最佳答案
这是我的程序的结果。
Start 1st worker
In the loop
Start invoke later
In the loop
In the loop
In the loop
In the loop
......
它启动第一个worker。然后部分代码在invokeLater中。因此请求被排队到事件队列中并启动循环。稍后执行invokeLater但不执行第二个worker,因为第一个worker仍在做一些工作。由于worker一个接一个地破坏并且它在单个worker队列上运行,所以第二个worker无法执行并且出现死锁。
感谢 MadProgrammer,我明白了这一点。希望这是正确的。
关于Java Foxtrot Worker 与 invokeLater 一起使用时产生死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33196021/