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);
}
cAMPy
  • 567
  • 2
  • 8
  • 25
  • 1
    Possible duplicate of [Method call to Future.get() blocks. Is that really desirable?](http://stackoverflow.com/questions/31092067/method-call-to-future-get-blocks-is-that-really-desirable) – aUserHimself May 16 '17 at 09:38
  • Calculations should be done on a second thread so the main thread (or gui thread) never freezes. – Obenland May 16 '17 at 09: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 – gati sahu May 16 '17 at 09:44
  • Also you can explore RxJava which provide some cool stuff for event base reactive programming. – gati sahu May 16 '17 at 09:49
  • @Obenland could you elaborate on that? – cAMPy May 16 '17 at 09:58
  • @cAMPy You may read https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html (the idea of this article works with other GUIs, not only swing) – Obenland May 17 '17 at 08:04

1 Answers1

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
Michael
  • 41,989
  • 11
  • 82
  • 128