Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java foxtrot Worker与invokeLater一起使用时会产生死锁_Java_Swing - Fatal编程技术网

Java foxtrot Worker与invokeLater一起使用时会产生死锁

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

我们正在使用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
......
它启动第一个工作进程。然后部分代码在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线程中。”-因此,我认为您必须对其进行测试并查看