/* * Copyright (C) 2007 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.common.util.concurrent; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import java.util.concurrent.RejectedExecutionException; /** * A {@link Future} that accepts completion listeners. Each listener has an * associated executor, and it is invoked using this executor once the future's * computation is {@linkplain Future#isDone() complete}. If the computation has * already completed when the listener is added, the listener will execute * immediately. * *

Purpose

* * Most commonly, {@code ListenableFuture} is used as an input to another * derived {@code Future}, as in {@link Futures#allAsList(Iterable) * Futures.allAsList}. Many such methods are impossible to implement efficiently * without listener support. * *

It is possible to call {@link #addListener addListener} directly, but this * is uncommon because the {@code Runnable} interface does not provide direct * access to the {@code Future} result. (Users who want such access may prefer * {@link Futures#addCallback Futures.addCallback}.) Still, direct {@code * addListener} calls are occasionally useful:

   {@code
 *   final String name = ...;
 *   inFlight.add(name);
 *   ListenableFuture future = service.query(name);
 *   future.addListener(new Runnable() {
 *     public void run() {
 *       processedCount.incrementAndGet();
 *       inFlight.remove(name);
 *       lastProcessed.set(name);
 *       logger.info("Done with {0}", name);
 *     }
 *   }, executor);}
* *

How to get an instance

* * Developers are encouraged to return {@code ListenableFuture} from their * methods so that users can take advantages of the utilities built atop the * class. The way that they will create {@code ListenableFuture} instances * depends on how they currently create {@code Future} instances: * * * Occasionally, an API will return a plain {@code Future} and it will be * impossible to change the return type. For this case, we provide a more * expensive workaround in {@code JdkFutureAdapters}. However, when possible, it * is more efficient and reliable to create a {@code ListenableFuture} directly. * * @author Sven Mawson * @author Nishant Thakkar * @since 1.0 */ public interface ListenableFuture extends Future { /** * Registers a listener to be {@linkplain Executor#execute(Runnable) run} on * the given executor. The listener will run when the {@code Future}'s * computation is {@linkplain Future#isDone() complete} or, if the computation * is already complete, immediately. * *

There is no guaranteed ordering of execution of listeners, but any * listener added through this method is guaranteed to be called once the * computation is complete. * *

Exceptions thrown by a listener will be propagated up to the executor. * Any exception thrown during {@code Executor.execute} (e.g., a {@code * RejectedExecutionException} or an exception thrown by {@linkplain * MoreExecutors#sameThreadExecutor inline execution}) will be caught and * logged. * *

Note: For fast, lightweight listeners that would be safe to execute in * any thread, consider {@link MoreExecutors#sameThreadExecutor}. For heavier * listeners, {@code sameThreadExecutor()} carries some caveats: First, the * thread that the listener runs in depends on whether the {@code Future} is * done at the time it is added and on whether it is ever canclled. In * particular, listeners may run in the thread that calls {@code addListener} * or the thread that calls {@code cancel}. Second, listeners may run in an * internal thread of the system responsible for the input {@code Future}, * such as an RPC network thread. Finally, during the execution of a {@code * sameThreadExecutor()} listener, all other registered but unexecuted * listeners are prevented from running, even if those listeners are to run * in other executors. * *

This is the most general listener interface. * For common operations performed using listeners, * see {@link com.google.common.util.concurrent.Futures} * * @param listener the listener to run when the computation is complete * @param executor the executor to run the listener in * @throws NullPointerException if the executor or listener was null * @throws RejectedExecutionException if we tried to execute the listener * immediately but the executor rejected it. */ void addListener(Runnable listener, Executor executor); }