在开始另一个任务之前等待任务在Java中完成

时间:2011-12-09 18:12:47

标签: java background task synchronous swingworker

我正在编写一个Java GUI应用程序,它正在进行一些XML解析和分析。由于某些方法需要一些时间才能完成,因此我将它们变成了任务(因此也能够利用netbeans自动生成的代码来更新主GUI的进度条和消息区域)。代码的某些区域我需要在运行下一个任务之前知道第一个任务的结果,但Java似乎默认并行运行它们。

基本上,如果我运行下面的代码,我会让它在任务运行时打印“已完成的任务1”,并且它也可能将下一个If语句评估为false(即使它是真的)因为任务尚未结束。

我一直在谷歌搜索并尝试一些事情,似乎已经碰壁了。有一些关于覆盖Task的done()方法的帖子,由于某种原因我无法做到,因为它被声明为final。我可以在主窗体/ EDT上调用task.get(),但这也会阻止更新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);    

        }

    }

来自interpreter / anotherInterpreter类:

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 个答案:

答案 0 :(得分:1)

您可能正在搜索CyclicBarrier,它是java并发包的一部分。它基本上可以阻止一个任务,直到另一个任务清除障碍。

有关详细信息,请参阅http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CyclicBarrier.html

答案 1 :(得分:0)

我假设您正在使用Swing应用框架中的tasks。 在当前任务在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;    
}