Provide Best Programming Tutorials

Callable Interface & Future Interface In Java

Introduction

Before JDK1.5 when we want to create a new thread, the most common way is to implements an interface called Runnable.

public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

This interface has a run() method with no return value.

If we want the thread returns a value we should use Callable Interface. This interface is added since JDK1.5.

It has a method called call() with return generic type return value. And this method can throw Exception.

public interface Callable<V> {
    /**
     * 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;
}

Example

The example below main thread will sleep 6 seconds after submitting the task. When the main thread wakes up it will get the result from the created thread. That thread will return a random generate a double number.

package multithreading.createNewThread;

import java.util.concurrent.*;


public class CallableDemo {

    public static void main(String[] args) {
        TaskGetInteger taskGetInteger = new TaskGetInteger();
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        try {
            Future<Double> future = executorService.submit(new TaskGetInteger());
            executorService.shutdown();
            Thread.sleep(6000);
            Double result = future.get();
            System.out.println("result:" + result);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

class TaskGetInteger implements Callable<Double> {

    @Override
    public Double call() throws Exception {
        Thread.sleep(5000);
        return Math.random();
    }
}

Future Interface

Notice we use submit method of ExecutorService. This method will return a Future object.

The Future interface has several methods can help us

  • cancel the task

  • check the task is canceled or not

  • check if the task finishes running

  • get running result

  • get running result for the given time

public interface Future<V> {

    /**
     * Attempts to cancel execution of this task.  This attempt will
     * fail if the task has already completed, has already been cancelled,
     * or could not be cancelled for some other reason. If successful,
     * and this task has not started when {@code cancel} is called,
     * this task should never run.  If the task has already started,
     * then the {@code mayInterruptIfRunning} parameter determines
     * whether the thread executing this task should be interrupted in
     * an attempt to stop the task.
     *
     * <p>After this method returns, subsequent calls to {@link #isDone} will
     * always return {@code true}.  Subsequent calls to {@link #isCancelled}
     * will always return {@code true} if this method returned {@code true}.
     *
     * @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);

    /**
     * Returns {@code true} if this task was cancelled before it completed
     * normally.
     *
     * @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}.
     *
     * @return {@code true} if this task completed
     */
    boolean isDone();

    /**
     * Waits if necessary for the computation to complete, and then
     * retrieves its result.
     *
     * @return the computed result
     * @throws CancellationException if the computation was cancelled
     * @throws ExecutionException if the computation threw an
     * exception
     * @throws InterruptedException if the current thread was interrupted
     * while waiting
     */
    V get() throws InterruptedException, ExecutionException;

    /**
     * Waits if necessary for at most the given time for the computation
     * to complete, and then retrieves its result, if available.
     *
     * @param timeout the maximum time to wait
     * @param unit the time unit of the timeout argument
     * @return the computed result
     * @throws CancellationException if the computation was canceled
     * @throws ExecutionException if the computation threw an
     * exception
     * @throws InterruptedException if the current thread was interrupted
     * while waiting
     * @throws TimeoutException if the wait timed out
     */
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

Leave a Reply

Close Menu