Ожидание завершения задачи в Java перед запуском другой задачи - PullRequest
3 голосов
/ 09 декабря 2011

Я пишу Java-приложение с графическим интерфейсом, которое выполняет анализ и анализ XML. Поскольку выполнение некоторых методов заняло некоторое время, я превратил их в задачи (и, таким образом, смог также использовать автоматически сгенерированный код netbeans для обновления индикатора выполнения и области сообщений основного графического интерфейса пользователя). В некоторых частях кода мне нужно знать результаты первой задачи перед выполнением следующей задачи, но Java, по-видимому, запускает их параллельно по умолчанию.

По сути, если бы я запустил приведенный ниже код, я бы получил его для печати «завершенной задачи 1» во время выполнения задачи, а также, вероятно, также оценил бы следующий оператор If как false (даже если бы он был истинным) потому что задание еще не закончено.

Я гуглил и пробовал несколько вещей и, похоже, врезался в стену. Были некоторые сообщения о переопределении метода done () в Task, чего я почему-то не могу сделать, потому что он объявлен как final. Я могу вызвать task.get () в главной форме / EDT, но это также блокирует обновление GUI (делая индикатор выполнения неактуальным).

Некоторые обобщенные фрагменты кода:

Из главного окна (также EDT)

    @Action
    private void someAction(java.awt.event.ActionEvent evt) {

        ApplicationContext C = getApplication().getContext();
        TaskMonitor M = C.getTaskMonitor();
        TaskService S = C.getTaskService();

        Task task = interpreter.parse();

        S.execute(task);
        M.setForegroundTask(task);

        System.out.println("finished task 1");

        if (interpreter.someBool() == true) {

            task = anotherInterpreter.parse();
            S.execute(task);
            M.setForegroundTask(task);    

        }

    }

Из классов переводчика / другого переводчика:

public Task parse() {


    Task task = new Task( org.jdesktop.application.Application.getInstance() ) {

        @Override
        protected Void doInBackground()  {

        // parse the file

        // set someBool to true if the another interpreter needs to be run

            return null;       

        }     

    };

    return task;    

}

Ответы [ 2 ]

1 голос
/ 09 декабря 2011

Вы, вероятно, ищете CyclicBarrier, который является частью пакета параллелизма Java. В основном это позволяет блокировать одну задачу, пока другая не очистит барьер.

Подробнее см. http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CyclicBarrier.html

0 голосов
/ 14 декабря 2011

Я предполагаю, что вы используете tasks из инфраструктуры приложения Swing.Вы можете использовать обратные вызовы, чтобы выполнить некоторые вещи, которые вы хотите после того, как ваша текущая задача завершится в doInBackground().

public class CustomTask<T, V> extends Task<T, V> {
  private Runnable callback = null;
  // add appropriate constructors
  public void setCallback(final Runnable r) {
    callback = r;
  }
  protected void executeCallback() {
    if (callback != null) {
      callback.run();
    }
  }
}


@Action
private void someAction(java.awt.event.ActionEvent evt) {
  final ApplicationContext C = getApplication().getContext();
  final TaskMonitor M = C.getTaskMonitor();
  final TaskService S = C.getTaskService();

  CustomTask task = interpreter.parse();
  task.setCallback(new Runnable(){
    public void run() {
      CustomTask t2 = anotherInterpreter.parse();
      S.execute(t2);
      M.setForegroundTask(t2);
    }
  });
  S.execute(task);
  M.setForegroundTask(task);

  System.out.println("finished task 1");
}


public CustomTask parse() {
  CustomTask task = new CustomTask( org.jdesktop.application.Application.getInstance() ) {
    @Override
    protected Void doInBackground()  {

      // parse the file
      executeCallback();
      return null;       
    }     
  };
  return task;    
}
...