1

I have an application where by clicking buttons (that number is defined) user creates tasks (Callable) that do some calculations. I want to be able to react when the task is finished. Using Future.get() blocks the application. Is there any way to be able to react when the Callable returns the result?

private static void startTask(int i){
    try{
        Future<Integer> future = executor.submit(callables.get(i-1));
        ongoingTasks.put(i, future);
        awaitResult(future, i);
    }
    catch(Exception e){
        e.printStackTrace();
    }
}

private static void awaitResult(Future<?> future, int taskNo) throws InterruptedException, ExecutionException{
    System.out.println("result : " + future.get());

    JButton b = buttons.get(taskNo);
    b.setEnabled(false);
}
6
  • 1
    Possible duplicate of Method call to Future.get() blocks. Is that really desirable? Commented May 16, 2017 at 9:38
  • Calculations should be done on a second thread so the main thread (or gui thread) never freezes. Commented May 16, 2017 at 9:40
  • You create some kind of callback where you will put your logic and run in a different thread so it will not be blocking Commented May 16, 2017 at 9:44
  • Also you can explore RxJava which provide some cool stuff for event base reactive programming. Commented May 16, 2017 at 9:49
  • @Obenland could you elaborate on that? Commented May 16, 2017 at 9:58

1 Answer 1

3

It sounds like you want a CompletableFuture. You have a function which is a "supplier" which supplies a value. This is the function that's actually doing the work.

You then have a function which accepts that value whenever the worker is done.

This is all asynchronous, so everything else carries on regardless of the outcome.

class Main
{
    private static Integer work() {
        System.out.println("work");
        return 3;
    }

    private static void done(Integer i) {
        System.out.println("done " + i);
    }

    public static void main (String... args)
    {
        CompletableFuture.supplyAsync(Main::work)  
                         .thenAccept(Main::done);

        System.out.println("end of main");
    }
}

Sample output:

end of main
work
done 3
Sign up to request clarification or add additional context in comments.

2 Comments

Unfortunately I have to use ExecutorService
@CAMPy you can pass the executorService as parameter to supplyAsync and other CmpletableFuture methods

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.