001 /* 002 * Copyright (C) 2007 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package com.google.common.util.concurrent; 018 019 import static com.google.common.base.Preconditions.checkNotNull; 020 021 import com.google.common.annotations.Beta; 022 023 import java.util.concurrent.CancellationException; 024 import java.util.concurrent.ExecutionException; 025 import java.util.concurrent.Executor; 026 import java.util.concurrent.TimeUnit; 027 import java.util.concurrent.TimeoutException; 028 import java.util.concurrent.locks.AbstractQueuedSynchronizer; 029 030 import javax.annotation.Nullable; 031 032 /** 033 * An abstract implementation of the {@link ListenableFuture} interface. This 034 * class is preferable to {@link java.util.concurrent.FutureTask} for two 035 * reasons: It implements {@code ListenableFuture}, and it does not implement 036 * {@code Runnable}. (If you want a {@code Runnable} implementation of {@code 037 * ListenableFuture}, create a {@link ListenableFutureTask}, or submit your 038 * tasks to a {@link ListeningExecutorService}.) 039 * 040 * <p>This class implements all methods in {@code ListenableFuture}. 041 * Subclasses should provide a way to set the result of the computation through 042 * the protected methods {@link #set(Object)} and 043 * {@link #setException(Throwable)}. Subclasses may also override {@link 044 * #interruptTask()}, which will be invoked automatically if a call to {@link 045 * #cancel(boolean) cancel(true)} succeeds in canceling the future. 046 * 047 * <p>{@code AbstractFuture} uses an {@link AbstractQueuedSynchronizer} to deal 048 * with concurrency issues and guarantee thread safety. 049 * 050 * <p>The state changing methods all return a boolean indicating success or 051 * failure in changing the future's state. Valid states are running, 052 * completed, failed, or cancelled. 053 * 054 * <p>This class uses an {@link ExecutionList} to guarantee that all registered 055 * listeners will be executed, either when the future finishes or, for listeners 056 * that are added after the future completes, immediately. 057 * {@code Runnable}-{@code Executor} pairs are stored in the execution list but 058 * are not necessarily executed in the order in which they were added. (If a 059 * listener is added after the Future is complete, it will be executed 060 * immediately, even if earlier listeners have not been executed. Additionally, 061 * executors need not guarantee FIFO execution, or different listeners may run 062 * in different executors.) 063 * 064 * @author Sven Mawson 065 * @since 1.0 066 */ 067 public abstract class AbstractFuture<V> implements ListenableFuture<V> { 068 069 /** Synchronization control for AbstractFutures. */ 070 private final Sync<V> sync = new Sync<V>(); 071 072 // The execution list to hold our executors. 073 private final ExecutionList executionList = new ExecutionList(); 074 075 /* 076 * Blocks until either the task completes or the timeout expires. Uses the 077 * sync blocking-with-timeout support provided by AQS. 078 */ 079 @Override 080 public V get(long timeout, TimeUnit unit) throws InterruptedException, 081 TimeoutException, ExecutionException { 082 return sync.get(unit.toNanos(timeout)); 083 } 084 085 /* 086 * Blocks until the task completes or we get interrupted. Uses the 087 * interruptible blocking support provided by AQS. 088 */ 089 @Override 090 public V get() throws InterruptedException, ExecutionException { 091 return sync.get(); 092 } 093 094 /* 095 * Checks if the sync is not in the running state. 096 */ 097 @Override 098 public boolean isDone() { 099 return sync.isDone(); 100 } 101 102 /* 103 * Checks if the sync is in the cancelled state. 104 */ 105 @Override 106 public boolean isCancelled() { 107 return sync.isCancelled(); 108 } 109 110 @Override 111 public boolean cancel(boolean mayInterruptIfRunning) { 112 if (!sync.cancel()) { 113 return false; 114 } 115 done(); 116 if (mayInterruptIfRunning) { 117 interruptTask(); 118 } 119 return true; 120 } 121 122 /** 123 * Subclasses can override this method to implement interruption of the 124 * future's computation. The method is invoked automatically by a successful 125 * call to {@link #cancel(boolean) cancel(true)}. 126 * 127 * <p>The default implementation does nothing. 128 * 129 * @since 10.0 130 */ 131 protected void interruptTask() { 132 } 133 134 @Override 135 public void addListener(Runnable listener, Executor exec) { 136 executionList.add(listener, exec); 137 } 138 139 /** 140 * Subclasses should invoke this method to set the result of the computation 141 * to {@code value}. This will set the state of the future to 142 * {@link AbstractFuture.Sync#COMPLETED} and call {@link #done()} if the 143 * state was successfully changed. 144 * 145 * @param value the value that was the result of the task. 146 * @return true if the state was successfully changed. 147 */ 148 protected boolean set(@Nullable V value) { 149 boolean result = sync.set(value); 150 if (result) { 151 done(); 152 } 153 return result; 154 } 155 156 /** 157 * Subclasses should invoke this method to set the result of the computation 158 * to an error, {@code throwable}. This will set the state of the future to 159 * {@link AbstractFuture.Sync#COMPLETED} and call {@link #done()} if the 160 * state was successfully changed. 161 * 162 * @param throwable the exception that the task failed with. 163 * @return true if the state was successfully changed. 164 * @throws Error if the throwable was an {@link Error}. 165 */ 166 protected boolean setException(Throwable throwable) { 167 boolean result = sync.setException(checkNotNull(throwable)); 168 if (result) { 169 done(); 170 } 171 172 // If it's an Error, we want to make sure it reaches the top of the 173 // call stack, so we rethrow it. 174 if (throwable instanceof Error) { 175 throw (Error) throwable; 176 } 177 return result; 178 } 179 180 /** 181 * <p>Subclasses can invoke this method to mark the future as cancelled. 182 * This will set the state of the future to {@link 183 * AbstractFuture.Sync#CANCELLED} and call {@link #done()} if the state was 184 * successfully changed. 185 * 186 * @return true if the state was successfully changed. 187 * @deprecated Most implementations will be satisfied with the default 188 * implementation of {@link #cancel(boolean)} and not need to call this method 189 * at all. Those that are not can delegate to {@code 190 * super.cancel(mayInterruptIfRunning)} or, to get behavior exactly equivalent 191 * to this method, {@code super.cancel(false)}. This method will be removed 192 * from Guava in Guava release 11.0. 193 */ 194 @Beta @Deprecated 195 protected final boolean cancel() { 196 boolean result = sync.cancel(); 197 if (result) { 198 done(); 199 } 200 return result; 201 } 202 203 /** 204 * <b>Deprecated.</b> {@linkplain #addListener Add listeners} (possible executed 205 * in {@link MoreExecutors#sameThreadExecutor}) to perform the work currently 206 * performed by your {@code done} implementation. This method will be removed 207 * from Guava in Guava release 11.0. 208 * 209 * Called by the success, failed, or cancelled methods to indicate that the 210 * value is now available and the latch can be released. 211 */ 212 @Beta @Deprecated protected 213 void done() { 214 executionList.execute(); 215 } 216 217 /** 218 * <p>Following the contract of {@link AbstractQueuedSynchronizer} we create a 219 * private subclass to hold the synchronizer. This synchronizer is used to 220 * implement the blocking and waiting calls as well as to handle state changes 221 * in a thread-safe manner. The current state of the future is held in the 222 * Sync state, and the lock is released whenever the state changes to either 223 * {@link #COMPLETED} or {@link #CANCELLED}. 224 * 225 * <p>To avoid races between threads doing release and acquire, we transition 226 * to the final state in two steps. One thread will successfully CAS from 227 * RUNNING to COMPLETING, that thread will then set the result of the 228 * computation, and only then transition to COMPLETED or CANCELLED. 229 * 230 * <p>We don't use the integer argument passed between acquire methods so we 231 * pass around a -1 everywhere. 232 */ 233 static final class Sync<V> extends AbstractQueuedSynchronizer { 234 235 private static final long serialVersionUID = 0L; 236 237 /* Valid states. */ 238 static final int RUNNING = 0; 239 static final int COMPLETING = 1; 240 static final int COMPLETED = 2; 241 static final int CANCELLED = 4; 242 243 private V value; 244 private Throwable exception; 245 246 /* 247 * Acquisition succeeds if the future is done, otherwise it fails. 248 */ 249 @Override 250 protected int tryAcquireShared(int ignored) { 251 if (isDone()) { 252 return 1; 253 } 254 return -1; 255 } 256 257 /* 258 * We always allow a release to go through, this means the state has been 259 * successfully changed and the result is available. 260 */ 261 @Override 262 protected boolean tryReleaseShared(int finalState) { 263 setState(finalState); 264 return true; 265 } 266 267 /** 268 * Blocks until the task is complete or the timeout expires. Throws a 269 * {@link TimeoutException} if the timer expires, otherwise behaves like 270 * {@link #get()}. 271 */ 272 V get(long nanos) throws TimeoutException, CancellationException, 273 ExecutionException, InterruptedException { 274 275 // Attempt to acquire the shared lock with a timeout. 276 if (!tryAcquireSharedNanos(-1, nanos)) { 277 throw new TimeoutException("Timeout waiting for task."); 278 } 279 280 return getValue(); 281 } 282 283 /** 284 * Blocks until {@link #complete(Object, Throwable, int)} has been 285 * successfully called. Throws a {@link CancellationException} if the task 286 * was cancelled, or a {@link ExecutionException} if the task completed with 287 * an error. 288 */ 289 V get() throws CancellationException, ExecutionException, 290 InterruptedException { 291 292 // Acquire the shared lock allowing interruption. 293 acquireSharedInterruptibly(-1); 294 return getValue(); 295 } 296 297 /** 298 * Implementation of the actual value retrieval. Will return the value 299 * on success, an exception on failure, a cancellation on cancellation, or 300 * an illegal state if the synchronizer is in an invalid state. 301 */ 302 private V getValue() throws CancellationException, ExecutionException { 303 int state = getState(); 304 switch (state) { 305 case COMPLETED: 306 if (exception != null) { 307 throw new ExecutionException(exception); 308 } else { 309 return value; 310 } 311 312 case CANCELLED: 313 throw new CancellationException("Task was cancelled."); 314 315 default: 316 throw new IllegalStateException( 317 "Error, synchronizer in invalid state: " + state); 318 } 319 } 320 321 /** 322 * Checks if the state is {@link #COMPLETED} or {@link #CANCELLED}. 323 */ 324 boolean isDone() { 325 return (getState() & (COMPLETED | CANCELLED)) != 0; 326 } 327 328 /** 329 * Checks if the state is {@link #CANCELLED}. 330 */ 331 boolean isCancelled() { 332 return getState() == CANCELLED; 333 } 334 335 /** 336 * Transition to the COMPLETED state and set the value. 337 */ 338 boolean set(@Nullable V v) { 339 return complete(v, null, COMPLETED); 340 } 341 342 /** 343 * Transition to the COMPLETED state and set the exception. 344 */ 345 boolean setException(Throwable t) { 346 return complete(null, t, COMPLETED); 347 } 348 349 /** 350 * Transition to the CANCELLED state. 351 */ 352 boolean cancel() { 353 return complete(null, null, CANCELLED); 354 } 355 356 /** 357 * Implementation of completing a task. Either {@code v} or {@code t} will 358 * be set but not both. The {@code finalState} is the state to change to 359 * from {@link #RUNNING}. If the state is not in the RUNNING state we 360 * return {@code false}. 361 * 362 * @param v the value to set as the result of the computation. 363 * @param t the exception to set as the result of the computation. 364 * @param finalState the state to transition to. 365 */ 366 private boolean complete(@Nullable V v, Throwable t, int finalState) { 367 if (compareAndSetState(RUNNING, COMPLETING)) { 368 this.value = v; 369 this.exception = t; 370 releaseShared(finalState); 371 return true; 372 } 373 374 // The state was not RUNNING, so there are no valid transitions. 375 return false; 376 } 377 } 378 }