How to fetch the output from a Thread?


  1. Task implemented using Callable can fetch the output of a Thread. Callable Interface is an enhancement to the Runnable interface which was introduced in Java 5 to capture thread's execution outcome.
  2. Unlike Runnable, Callable cannot be run using Thread Class because Thread class accepts only Runnable. Callable has to be run by submitting it to ExecutorService only.
Callable<String> task = new Callable<String>() {
      @Override
      public String call() throws Exception {
   return "Hello World";
       }
}; 
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<String> future = ExecutorService.submit(task); // Task is submitted to executor.
String result = future.get(); // Main thread waits for callable task completion 
  1. ExecutorService returns parameterized Future object(Future<V>) immediately after submitting the callable Interface (without waiting for the task completion).
  2. If you want to access the outcome of the task at any time, you can access it by using future.get()
  3.  submit() is a non-blocking call since it does not impact the current thread execution. But, get() is a blocking call which means the current thread has to wait for the callable task completion.
  4. isDone() is to check the state of the Future task. It will return true if the task is completed. 
  5. Instead of directly calling get() method which is a blocking call, it is a good practice to check the status of the Future task periodically and once the isDone() returns true, get() method should be called to fetch the result.
In this example, a callable task of 10secs (A task of sleep for 10 secs and return random long number) is submitted to the Executor service. ExecutorService returned Future<Long>immedeatly. 
Then the main thread polled for every 2.5 secs to check the task completion by checking the isDone() condition on the Future Object. 
Once the condition is satisfied, the current thread collected the result using future.get() (In an ideal scenario, the current thread would be busy doing some other process and periodically checks for the result). 

public class CallableExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newSingleThreadExecutor();

        Future<Long> future = executorService.submit(()->{
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return new Random().nextLong();
        });

        while(!future.isDone()){
            System.out.println("Task is still going on");
            try {
                Thread.sleep(2500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        Long result = future.get();
        System.out.println("Task is completed, the result is :"+ result);
        executorService.shutdown();
    }
}

Output
Task is still going on
Task is still going on
Task is still going on
Task is still going on
Task is completed, the result is :-4055592278692615646


Comments

Popular posts from this blog

Distributed database design using CAP theorem

SQL Analytical Functions - Partition by (to split resultset into groups)

Easy approach to work with files in Java - Java NIO(New input output)