Search code examples
javabackgroundtasksynchronousswingworker

Waiting for a task to finish in Java before starting another task


I'm writing a Java GUI application that is doing some XML parsing and analysis. Since some of the methods take some time to complete, I made them into tasks (and thus was also able to utilize the netbeans autogenerated code to update the progress bar and message area of the main GUI). There are some areas of the code where I need to know the results of the first task before running the next task, but Java seems to run them in parallel by default.

Basically, if I ran the code below, I'd get it to print "finished task 1" while the task was running, and also it would also likely evaluate the next If statement as false (even if it were true) because the task had not yet finished.

I've been googling and trying few things and seem to have hit a wall. There were some posts about overriding the done() method of Task, which for some reason I cannot do because it's declared as a final. I can call task.get() on the main form/EDT, but that also blocks updating the GUI (making the progress bar irrelevant).

Some generalized code snippets:

From the main window (also the 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);    

        }

    }

From the interpreter / anotherInterpreter classes:

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;    

}

Solution

  • you are probably searching for the CyclicBarrier which is part of the java concurrency package. It basically enables you to block one task until the other one clears the barrier.

    See http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CyclicBarrier.html for some details