/* * Copyright (C) 2009 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 static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly; import com.google.common.annotations.Beta; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicBoolean; /** * Utilities necessary for working with libraries that supply plain {@link * Future} instances. Note that, whenver possible, it is strongly preferred to * modify those libraries to return {@code ListenableFuture} directly. * * @author Sven Mawson * @since 10.0 (replacing {@code Futures.makeListenable}, which * existed in 1.0) */ @Beta public final class JdkFutureAdapters { /** * Assigns a thread to the given {@link Future} to provide {@link * ListenableFuture} functionality. * *
Warning: If the input future does not already implement {@code * ListenableFuture}, the returned future will emulate {@link * ListenableFuture#addListener} by taking a thread from an internal, * unbounded pool at the first call to {@code addListener} and holding it * until the future is {@linkplain Future#isDone() done}. * *
Prefer to create {@code ListenableFuture} instances with {@link
* SettableFuture}, {@link MoreExecutors#listeningDecorator(
* java.util.concurrent.ExecutorService)}, {@link ListenableFutureTask},
* {@link AbstractFuture}, and other utilities over creating plain {@code
* Future} instances to be upgraded to {@code ListenableFuture} after the
* fact.
*/
public static Warning: If the input future does not already implement {@code
* ListenableFuture}, the returned future will emulate {@link
* ListenableFuture#addListener} by submitting a task to the given executor at
* the first call to {@code addListener}. The task must be started by the
* executor promptly, or else the returned {@code ListenableFuture} may fail
* to work. The task's execution consists of blocking until the input future
* is {@linkplain Future#isDone() done}, so each call to this method may
* claim and hold a thread for an arbitrary length of time. Use of bounded
* executors or other executors that may fail to execute a task promptly may
* result in deadlocks.
*
* Prefer to create {@code ListenableFuture} instances with {@link
* SettableFuture}, {@link MoreExecutors#listeningDecorator(
* java.util.concurrent.ExecutorService)}, {@link ListenableFutureTask},
* {@link AbstractFuture}, and other utilities over creating plain {@code
* Future} instances to be upgraded to {@code ListenableFuture} after the
* fact.
*
* @since 12.0
*/
public static If the delegate future is interrupted or throws an unexpected unchecked
* exception, the listeners will not be invoked.
*/
private static class ListenableFutureAdapter