Java Future

In multithreaded programming, Java Future with Callable is very important for tasks which we want to know status and get the returned object.

This article give us an example for how to work with Future and Callable inside.

Related Articles:
Java Thread Pool – ExecutorService
Java 8 CompletableFutures
Java 8 CompletableFuture Handle Exception
Java 8 Multiple CompletableFutures

I. Introduction
1. Callable
public interface Callable {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

The Callable interface is similar to Runnable, which are designed for classes’ instances executed by thread. However, Callable can return a result and throw a checked exception.

We execute Callable in a thread pool by using an Executor, which provides methods to manage termination or produce a Future for asynchronous tasks.

public interface ExecutorService extends Executor {

    void shutdown();
    boolean isTerminated();
    boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
     Future submit(Callable task);
}
2. Future

Executor submit method with Callable as parameter return a Future object:

Future future = executor.submit(new Callable() {...});

A Future represents the result of an asynchronous computation. It has methods to check completion, or wait for completion.
The result of the completion can be retrieved using method get when it completes, and is blocked until it is ready.

public interface Future {

    /**
     * @param mayInterruptIfRunning {@code true} if the thread executing this
     * task should be interrupted; otherwise, in-progress tasks are allowed
     * to complete
     * @return {@code false} if the task could not be cancelled,
     * typically because it has already completed normally;
     * {@code true} otherwise
     */
    boolean cancel(boolean mayInterruptIfRunning);

    /**
     * @return {@code true} if this task was cancelled before it completed
     */
    boolean isCancelled();

    /**
     * Returns {@code true} if this task completed.
     *
     * Completion may be due to normal termination, an exception, or
     * cancellation -- in all of these cases, this method will return
     * {@code true}.
     */
    boolean isDone();

    /**
     * Waits if necessary for the computation to complete, and then
     * retrieves its result.
     *
     * @return the computed result
     */
    V get() throws InterruptedException, ExecutionException;

    /**
     * @param timeout the maximum time to wait
     * @param unit the time unit of the timeout argument
     * @return the computed result
     */
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

The V get(...) method will throws:
CancellationException if the computation was cancelled
ExecutionException if the computation threw an exception
InterruptedException if the current thread was interrupted while waiting
TimeoutException if the wait timed out

II. Example
package com.javasampleapproach.future;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class MainApp {
	static ExecutorService executor = Executors.newFixedThreadPool(10);

	public static void main(String[] args) throws Exception {

		Future future = makeFuture("running Future");

		// other statements
		for (int i = 1; i <= 3; i++) {
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("running outside... " + i + " time");
		}

		String contents = future.get();
		System.out.println(contents);
	}

	static Future makeFuture(String inString) throws Exception {
		return executor.submit(new Callable() {
			@Override
			public String call() throws Exception {
				for (int i = 1; i <= 5; i++) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("running inside Future... " + i + " sec");
				}
				return "Done " + inString;
			}
		});
	}
}

Check results in Console Screen:

running outside... 1 time
running inside Future... 1 sec
running outside... 2 time
running outside... 3 time
running inside Future... 2 sec
running inside Future... 3 sec
running inside Future... 4 sec
running inside Future... 5 sec
Done running Future


By grokonez | December 12, 2016.

Last updated on June 4, 2017.



Related Posts


Got Something To Say:

Your email address will not be published. Required fields are marked *

*