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

标签 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.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/

相关文章:

java - 从字符串创建 URL

java - 将图像大小调整为从 Swing 应用程序中的文件选择器动态获取的 JLabel 的大小

java - 我收到 HTTPS URL 的 java.io.FileNotFoundException

java - 如何使用java邮件在单个邮件中发送由函数返回的两个附件?

Java JCE 提供者 - "clean room implementation"是什么意思?

Java 打开 JFrame 内部的 URL

java - 如何使用 esc 或按钮 Java 终止程序

java - 使用 PlainDocument 在 JTextField 中移动插入符号

java - 无法弄清楚如何返回要添加到框架的多边形绘图数据

java - Hibernate查询异常: Cannot create critieria on owning entity