Callables and Futures Core Java

A Runnable encapsulates a task that runs asynchronously; you can think of it as an asynchronous method with no parameters and no return value. A Callable is similar to a Runnable,but it returns a value. The Callable interface is a parameterized type, with a single method call.

The type parameter is the type of the returned value. For example, a Callable <Integer> represents an asynchronous computation that eventually returns an Integer object.

A Future holds the result of an asynchronous computation. You can start a computation, give someone the Future object, and forget about it. The owner of the Future object can obtain the result when it is ready.

The Future interface has the following methods:

A call to the first get method blocks until the computation is finished. The second method throws a TimeoutException if the call timed out before the computation finished. If the thread running the computation is interrupted, both methods throw an InterruptedException.

If the computation has already finished, then get returns immediately. The isDone method returns false if the computation is still in progress, true if it is finished. You can cancel the computation with the cancel method. If the computation has not yet started, it is canceled and will never start. If the computation is currently in progress, then it is interrupted if the mayInterrupt parameter is true.

The FutureTask wrapper is a convenient mechanism for turning a Callable into both a Future and a Runnable—it implements both interfaces. For example:

The program in Listing below puts these concepts to work. This program is similar to the preceding example that found files containing a given keyword. However, now we will merely count the number of matching files. Thus, we have a long-running task that yields an integer value—an example of a Callable<Integer>.

Then we construct a FutureTask object from the MatchCounter and use it to start a thread.

Of course, the call to get blocks until the result is actually available. Inside the call method, we use the same mechanism recursively. For each subdirectory, we produce a new MatchCounter and launch a thread for it. We also stash the FutureTaskobjects away in an ArrayList<Future<Integer>>. At the end, we add up all results:

Each call to get blocks until the result is available. Of course, the threads run in parallel, so there is a good chance that the results will all be available at about the same time.

  • V call()
    runs a task that yields a result.
  • V get()
  • V get(long time, TimeUnit unit)
    gets the result, blocking until it is available or the given time has elapsed. The second method throws a TimeoutException if it was unsuccessful.
  • boolean cancel(boolean mayInterrupt)
    attempts to cancel the execution of this task. If the task has already started and the mayInterrupt parameter is true, it is interrupted. Returns true if the cancellation was successful.
  • boolean isCancelled()
    returns true if the task was canceled before it completed.
  • boolean isDone()
    returns true if the task completed, through normal completion, cancellation, or an exception.
  • FutureTask(Callable<V> task)
  • FutureTask(Runnable task, V result)
    constructs an object that is both a Future<V>and a Runnable.

All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd Protection Status

Core Java Topics