等待摇摆工作者而不阻止EDT进行同步呼叫

时间:2015-11-03 07:18:40

标签: java multithreading swing

我们有UI,可以从各种动作听众中创建多个摇摆工作者。还有另一种动作侦听器方法,如

void actionListener()
{
  boolean b = performSomeTask();
  if(b)
  {
    do something
  }
}

boolean performTask()
{
  wait all until all swing workers complete
  (required swing workers are internally maintained)

  do something
  return some condition
}

我们在performTask()中使用foxtrot Worker完成了这项工作。它会循环,直到在foxtrot任务中swingworker计数变为0。现在问题是一个正在运行的摇摆工作者试图将任务推向foxtrot工人,但工人已经被吓倒了。由于foxtrot工作者是单线程的,它最终会陷入死锁。试过ConcurrentWorker,但它也不起作用。

有没有其他方法可以实现这个目标?主要要求是peformTask应该返回一些值(监听器基础解决方案不起作用)并且它不应该阻止EDT,因为swingworkers可能会在完成之前将事情推送到EDT

以下示例包含一些类似的行为

import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
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.JTextField;

import foxtrot.ConcurrentWorker;
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 b = true;

  public FoxTrotExample()
  {
    super("Foxtrot Example");

    JTextField txtF = new JTextField();

    final JButton alam = new JButton("Alam");
    alam.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {

        try
        {
          Worker.post(new Task()
          {
            public Object run() throws Exception
            {
              System.out.println("Alam will trigger in 2 sec");

              Thread.sleep(5000);
              System.out.println("Alam going to ring");
              return "";
            }
          });
          System.out.println("Ring");
          b = false;
        }
        catch (Exception ex)
        {
          ex.printStackTrace();
        }
      }
    });

    final JButton button = new JButton("Take a nap !");

    button.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        button.setText("Sleeping...");

        String text = null;
        try
        {
          text = (String) Worker.post(new Task()
          {
            public Object run() throws Exception
            {
              //wait for other task get executed
              while (b)
              {
                System.out.println("In the loop");
                Thread.sleep(2000);
              }

              return "Slept !";
            }
          });
        }
        catch (Exception x)
        {
          x.printStackTrace();
        }

        button.setText(text);

      }
    });

    setDefaultCloseOperation(DISPOSE_ON_CLOSE);

    Container c = getContentPane();
    c.setLayout(new GridBagLayout());
    c.add(button, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL,
        new Insets(5, 5, 5, 5), 0, 0));
    c.add(alam, new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL,
        new Insets(5, 5, 5, 5), 0, 0));
    txtF.requestFocusInWindow();
    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);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
  }

0 个答案:

没有答案