Future

Several methods of the Future interface

  • boolean cancel(boolean mayInterruptIfRunning); Cancel unfinished tasks and interrupt ongoing tasks
  • boolean isCancelled(); Whether to complete before being cancelled
  • boolean isDone();
  • V get() throws InterruptedException, ExecutionException; Block the current thread and so on
  • V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; Specify a timeout for waiting
    /**
     * 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);

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

    /**
     * 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(a);

    /**
     * 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(a) 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 cancelled
     * @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;
}
Copy the code

FutureTask

FutureTask implements the Runnable and Future interfaces. As Runnable interfaces are implemented, FutureTask objects can be submitted to ThreadPoolExecutor for execution or executed by Thread. Since the Future interface is implemented, it can also be used to obtain the execution results of tasks.

Teapot boiling problem

Various approaches, such as Thread.join(), CountDownLatch, and even blocking queues, can be used, but for today we’ll use the Future feature.

public class ThreadPoolDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2.4.5, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(), r -> new Thread(r, "bb-thread-" + r.hashCode()));

        FutureTask<String> t1 = new FutureTask<>(new Task1());
        FutureTask<String> t2 = new FutureTask<>(newTask2(t1)); threadPoolExecutor.submit(t1); threadPoolExecutor.submit(t2); System.out.println(t2.get()); }}class Task1 implements Callable<String>{

    @Override
    public String call(a) throws Exception {
        System.out.println("Wash the teapot...");
        TimeUnit.SECONDS.sleep(1);
        System.out.println("Wash the cups...");
        TimeUnit.SECONDS.sleep(2);
        System.out.println("Get the tea...");
        TimeUnit.SECONDS.sleep(1);
        return "Longjing"; }}class Task2 implements Callable<String>{
    FutureTask<String> task1futureTask;

    public Task2(FutureTask<String> task1futureTask) {
        this.task1futureTask = task1futureTask;
    }

    @Override
    public String call(a) throws Exception {
        System.out.println("Wash the kettle...");
        TimeUnit.SECONDS.sleep(1);
        System.out.println("Boil the water...");
        TimeUnit.SECONDS.sleep(5);
        // Get the result of another thread
        String tf = task1futureTask.get();
        System.out.println("Get the tea :"+tf);
        System.out.println("Tea...");
        return "Tea."+ tf; }}Copy the code