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

时间:2015-10-18 08:50:13

标签: java swing

我们正在使用foxtrot包停止摇摆应用。

但是在下面的代码中,它会陷入僵局。

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在这里的行为?

1 个答案:

答案 0 :(得分:0)

这是我的计划的结果。

Start 1st worker
In the loop
Start invoke later
In the loop
In the loop
In the loop
In the loop
......

它启动第一个worker。然后部分代码在invokeLater.So请求被引入事件队列并启动循环。后者执行invokeLater但不执行第二个worker,因为第一个worker仍在做一些work.Since工作者一个接一个地破坏它并且它在一个工作队列上运行第二个工作者无法执行并且死锁来了。

感谢MadProgrammer,我理解这一点。希望这是正确的。