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

org.glassfish.jersey.internal.guava.ListenableFuture Maven / Gradle / Ivy

There is a newer version: 4.0.0-M1
Show newest version
/*
 * 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 org.glassfish.jersey.internal.guava;

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 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 */ 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}. For heavier * listeners, {@code directExecutor()} carries some caveats. For * example, the listener may run on an unpredictable or undesirable thread: *

*

    *
  • If this {@code Future} is done at the time {@code addListener} is * called, {@code addListener} will execute the listener inline. *
  • If this {@code Future} is not yet done, {@code addListener} will * schedule the listener to be run by the thread that completes this {@code * Future}, which may be an internal system thread such as an RPC network * thread. *
*

*

Also note that, regardless of which thread executes the * {@code directExecutor()} listener, all other registered but unexecuted * listeners are prevented from running during its execution, 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 * Futures}. For a simplified but general * listener interface, see {@link * Futures#addCallback addCallback()}. * * @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