4
votes

The Java Future object is used to get the result of asynchronous computation which is performed by a parallel thread(Executors). We call Future.get() method and wait until result is ready. This example shows a non blocking way for retrieving result from Future. java-implement-java-non-blocking-futures.

NonBlockingExecutor executor = new NonBlockingExecutor(Executors.newSingleThreadExecutor());

NonBlockingFuture<Integer> future = executor.submitNonBlocking(new Callable<Integer>() {

            @Override
            public Integer call() throws Exception {
                String threadName = Thread.currentThread().getName();
                System.out.println(threadName);
                //print -> pool-1-thread-1
                return 1;
            }
});

future.setHandler(new FutureHandler<Integer>() {

       @Override
       public void onSuccess(Integer value) {
            String threadName = Thread.currentThread().getName();
            System.out.println(threadName);
            //print -> pool-1-thread-1
       }

       @Override
       public void onFailure(Throwable e) {
            System.out.println(e.getMessage());
       }
 });

 Thread.sleep(50000);

In this onSuccess() method is called after parallel execution is finish. The problem is onSuccess() method is not running on the main thread. I want to perform onSuccess() method on the main thread. How can i fix this. Thanks

3
Presumably, your main thread is busy doing something else.Sotirios Delimanolis
Honestly, I don't know how to go about that with executors. Fail all else, you could always 'hack' it in mind you - just pass some data into a collection, then the main thread sees the data in this collection and responds appropriately.KookieMonster
Can we do this by using Java 8 CompletableFuture ?Tharanga

3 Answers

8
votes

This is supported with CompletableFutures.

    CompletableFuture.runAsync(() -> {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName);
        //print -> pool-1-thread-1
    }).whenComplete((task, throwable) -> {
        if(throwable != null) {
           System.out.println(e.getMessage());
        } else {
            String threadName = Thread.currentThread().getName();
            System.out.println(threadName);
            //print -> pool-1-thread-1
        }
    });

The caveat here is that the future would run the whenComplete task on the executing thread and not the submitting thread.

2
votes

The point of a Future is that the associated computation is performed in a separate thread. The onSuccess method is a way for that separate thread to say that it has finished performing the computation. It would make no sense for the main thread to call onSuccess, since the main thread doesn't perform the computation and doesn't know when the computation is complete.

From the main thread, if you want to wait for the computation to complete and get the result, call get(). If you want to check if the computation is complete and keep doing other things if it is not complete yet, call isDone() or get(long, TimeUnit). If you want to terminate the computation whether or not it is complete, call cancel().

2
votes

I want to perform onSuccess() method on the main thread. How can i fix this.

You can't. Nothing in Java can make a thread stop what it was doing, do something else for a moment, and then go back to whatever it was doing. Some programming environments have a feature like that---Unix signals, hardware interrupts---But it's just not part of the Java language.