0

We have UI which create multiple swing workers from various action listeners. There is another action listener method like

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
}

We have done this using foxtrot Worker in performTask(). It loops until swingworker count becomes 0 in a foxtrot task. Now the issue a running swingworker try to push task to foxtrot worker but the worker is already accupied. Since foxtrot worker is single threaded it ends up in a dead lock. Tried the ConcurrentWorker but it too does not work.

Is here any other way to achieve this target? Main requirement is peformTask should return some value(listener base solution wont work) and it should not block EDT since swingworkers may push things to EDT before they complete

Following example contains somewhat similar behaviour

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);
  }
hmc
  • 85
  • 1
  • 10
  • 1
    It's really hard to provide an answer here without to see your code. Please provide a [SSCCE](http://sscce.org). – Sergiy Medvynskyy Nov 03 '15 at 07:43
  • @SergiyMedvynskyy Add a simple example with similar issue – hmc Nov 03 '15 at 08:03
  • 1
    Use an `ExecutorService` and submit all the workers to it – MadProgrammer Nov 03 '15 at 08:05
  • @MadProgrammer Can you explain a bit more. – hmc Nov 03 '15 at 08:46
  • It's difficult to know what to suggest, as you have no SwingWorkers in your example, but you can use the submit (submitAll?) feature of the ExecutorService to execute a list of SwingWorlers which won't return until all the workers have competed (or failed). You'd then be able to use Foxtrot to execute this – MadProgrammer Nov 03 '15 at 08:50
  • Also, I honestly think you're confusing your self through the use of Foxtrot, while powerful, if you don't use it wisely, it will turn around and bite you – MadProgrammer Nov 03 '15 at 08:50
  • @MadProgrammer I agree with your comment regarding foxtrot exactly the same thing has happens with the time. So looking for an alternative. – hmc Nov 03 '15 at 08:58
  • @MadProgrammer Regarding the ExecuterService.submit isn't it asynchronous? https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html according to this Future is the one to monitor the progress. So executerservice.submit will not blocked until it get finished – hmc Nov 03 '15 at 09:00
  • @hmc Foxtrots a powerful and useful API, but you need to know when it's the right tool for the job. Much of you code could be made to use a `SwingWorker` and an observer pattern, which would probably be the more traditional method – MadProgrammer Nov 03 '15 at 09:01
  • @hmc It's `invokeAll` you want, which block until the `List` of `Callable`s has been completed – MadProgrammer Nov 03 '15 at 09:02
  • 2
    Posible duplicate of [this](http://stackoverflow.com/q/11366330/230513). – trashgod Nov 03 '15 at 09:58
  • @trashgod Can't use countdownlatch because it blocks EDT. so if the worker perform a SwingUtilities.invokeAndWait() it will end up in dead lock as well – hmc Nov 04 '15 at 08:27
  • Block on `latch.await()` in the background of another worker whose `done()` will run on the EDT. – trashgod Nov 04 '15 at 13:11

0 Answers0