Java foxtrot Worker与invokeLater一起使用时会产生死锁
我们正在使用foxtrot包停止冻结swing应用程序 但在下面的代码中,它会造成死锁Java foxtrot Worker与invokeLater一起使用时会产生死锁,java,swing,Java,Swing,我们正在使用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.JBu
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
......
它启动第一个工作进程。然后部分代码在invokeLater中。因此请求被分配到事件队列中并启动循环。稍后执行invokeLater,但不执行第二个工作进程,因为第一个工作进程仍在做一些工作。由于工作进程一个接一个地破坏,并且它在单个工作进程队列上运行,第二个工作进程无法执行并死锁来了
多亏了MadProgrammer,我明白了这一点。希望这是正确的。这是我程序的结果
Start 1st worker
In the loop
Start invoke later
In the loop
In the loop
In the loop
In the loop
......
它启动第一个工作进程。然后部分代码在invokeLater中。因此请求被分配到事件队列中并启动循环。稍后执行invokeLater,但不执行第二个工作进程,因为第一个工作进程仍在做一些工作。由于工作进程一个接一个地破坏,并且它在单个工作进程队列上运行,第二个工作进程无法执行并死锁来了
多亏了MadProgrammer,我明白了这一点。希望这是正确的。我没有想到,
invokeLater
能够在工作者
完成之前执行请求,但这假设它是在原始调度程序上执行的,而不是在foxtrot调度程序上执行的。你知道foxtrot做了什么,不是吗?事实上,我认为你的“死锁”是由你的while循环引起的,因为原始EDT或foxtrotI都不知道foxtrot的调度或处理。但是为什么第二个工人不工作呢?所以,快速测试一下,如果你移除while循环,将允许执行第二个任务。这似乎表明任务已发布到原始调度程序中,但当第一个任务正在运行时,调度程序没有处理文档中的新事件(第一个工作进程是控制)“Foxtrot的ConcurrentWorker是一个与Worker类似的同步解决方案。工作人员将要在单个工作人员队列中运行的任务或作业排队,以便一个接一个地执行,而在ConcurrentWorker中,任务或作业在发布后立即运行,并且每个任务或作业都在其自己的工作线程中。“-因此,我要说的是,您必须对它进行一次测试,看,我没有想到,invokeLater
将能够执行请求,直到工作者
完成,但这假设它是在原始调度程序上执行的,而不是在foxtrot调度程序上执行的。你知道foxtrot做了什么,不是吗?事实上,我认为你的“死锁”是由你的while循环引起的,因为原始EDT或foxtrotI都不知道foxtrot的调度或处理。但是为什么第二个工人不工作呢?所以,快速测试一下,如果你移除while循环,将允许执行第二个任务。这似乎表明任务已发布到原始调度程序中,但当第一个任务正在运行时,调度程序没有处理文档中的新事件(第一个工作进程是控制)“Foxtrot的ConcurrentWorker是一个与Worker类似的同步解决方案。在这里,Worker将要运行的任务或作业排在单个Worker队列中,以便它们一个接一个地执行,而在ConcurrentWorker中,任务或作业在发布后立即运行,并且每个任务或作业都在其自己的Worker线程中。”-因此,我认为您必须对其进行测试并查看