All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.common.util.concurrent.ListenableFuture Maven / Gradle / Ivy

/*
 * 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 com.google.common.annotations.GwtCompatible;

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.
 * 
 * 

See the Guava User Guide article on * {@code ListenableFuture}. * *

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 {@linkplain Futures * utilities built atop the class}. The way that they will create {@code * ListenableFuture} instances depends on how they currently create {@code * Future} instances: *

    *
  • If they are returned from an {@code ExecutorService}, convert that * service to a {@link ListeningExecutorService}, usually by calling {@link * MoreExecutors#listeningDecorator(ExecutorService) * MoreExecutors.listeningDecorator}. (Custom executors may find it more * convenient to use {@link ListenableFutureTask} directly.) *
  • If they are manually filled in by a call to {@link FutureTask#set} or a * similar method, create a {@link SettableFuture} instead. (Users with more * complex needs may prefer {@link AbstractFuture}.) *
* *

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 */ @GwtCompatible 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#directExecutor direct execution}) will be caught and * logged. * *

Note: For fast, lightweight listeners that would be safe to execute in * any thread, consider {@link MoreExecutors#directExecutor}. Otherwise, avoid * it. Heavyweight {@code directExecutor} listeners can cause problems, and * these problems can be difficult to reproduce because they depend on timing. * For example: * *

    *
  • The listener may be executed by the caller of {@code addListener}. That * caller may be a UI thread or other latency-sensitive thread. This can harm * UI responsiveness. *
  • The listener may be executed by the thread that completes this {@code * Future}. That thread may be an internal system thread such as an RPC * network thread. Blocking that thread may stall progress of the whole * system. It may even cause a deadlock. *
  • The listener may delay other listeners, even listeners that are not * themselves {@code directExecutor} listeners. *
* *

This is the most general listener interface. For common operations * performed using listeners, see {@link Futures}. For a simplified but * general listener interface, see {@link Futures#addCallback addCallback()}. * *

Memory consistency effects: Actions in a thread prior to adding a listener * * happen-before its execution begins, perhaps in another thread. * * @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); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy