1 7 8 package java.util.concurrent; 9 import java.util.concurrent.locks.*; 10 11 34 public class FutureTask<V> implements Future <V>, Runnable { 35 36 private final Sync sync; 37 38 45 public FutureTask(Callable <V> callable) { 46 if (callable == null) 47 throw new NullPointerException (); 48 sync = new Sync(callable); 49 } 50 51 63 public FutureTask(Runnable runnable, V result) { 64 sync = new Sync(Executors.callable(runnable, result)); 65 } 66 67 public boolean isCancelled() { 68 return sync.innerIsCancelled(); 69 } 70 71 public boolean isDone() { 72 return sync.innerIsDone(); 73 } 74 75 public boolean cancel(boolean mayInterruptIfRunning) { 76 return sync.innerCancel(mayInterruptIfRunning); 77 } 78 79 public V get() throws InterruptedException , ExecutionException { 80 return sync.innerGet(); 81 } 82 83 public V get(long timeout, TimeUnit unit) 84 throws InterruptedException , ExecutionException , TimeoutException { 85 return sync.innerGet(unit.toNanos(timeout)); 86 } 87 88 97 protected void done() { } 98 99 104 protected void set(V v) { 105 sync.innerSet(v); 106 } 107 108 114 protected void setException(Throwable t) { 115 sync.innerSetException(t); 116 } 117 118 122 public void run() { 123 sync.innerRun(); 124 } 125 126 134 protected boolean runAndReset() { 135 return sync.innerRunAndReset(); 136 } 137 138 146 private final class Sync extends AbstractQueuedSynchronizer { 147 148 private static final int RUNNING = 1; 149 150 private static final int RAN = 2; 151 152 private static final int CANCELLED = 4; 153 154 155 private final Callable <V> callable; 156 157 private V result; 158 159 private Throwable exception; 160 161 166 private volatile Thread runner; 167 168 Sync(Callable <V> callable) { 169 this.callable = callable; 170 } 171 172 private boolean ranOrCancelled(int state) { 173 return (state & (RAN | CANCELLED)) != 0; 174 } 175 176 179 protected int tryAcquireShared(int ignore) { 180 return innerIsDone()? 1 : -1; 181 } 182 183 187 protected boolean tryReleaseShared(int ignore) { 188 runner = null; 189 return true; 190 } 191 192 boolean innerIsCancelled() { 193 return getState() == CANCELLED; 194 } 195 196 boolean innerIsDone() { 197 return ranOrCancelled(getState()) && runner == null; 198 } 199 200 V innerGet() throws InterruptedException , ExecutionException { 201 acquireSharedInterruptibly(0); 202 if (getState() == CANCELLED) 203 throw new CancellationException (); 204 if (exception != null) 205 throw new ExecutionException (exception); 206 return result; 207 } 208 209 V innerGet(long nanosTimeout) throws InterruptedException , ExecutionException , TimeoutException { 210 if (!tryAcquireSharedNanos(0, nanosTimeout)) 211 throw new TimeoutException (); 212 if (getState() == CANCELLED) 213 throw new CancellationException (); 214 if (exception != null) 215 throw new ExecutionException (exception); 216 return result; 217 } 218 219 void innerSet(V v) { 220 for (;;) { 221 int s = getState(); 222 if (ranOrCancelled(s)) 223 return; 224 if (compareAndSetState(s, RAN)) 225 break; 226 } 227 result = v; 228 releaseShared(0); 229 done(); 230 } 231 232 void innerSetException(Throwable t) { 233 for (;;) { 234 int s = getState(); 235 if (ranOrCancelled(s)) 236 return; 237 if (compareAndSetState(s, RAN)) 238 break; 239 } 240 exception = t; 241 result = null; 242 releaseShared(0); 243 done(); 244 } 245 246 boolean innerCancel(boolean mayInterruptIfRunning) { 247 for (;;) { 248 int s = getState(); 249 if (ranOrCancelled(s)) 250 return false; 251 if (compareAndSetState(s, CANCELLED)) 252 break; 253 } 254 if (mayInterruptIfRunning) { 255 Thread r = runner; 256 if (r != null) 257 r.interrupt(); 258 } 259 releaseShared(0); 260 done(); 261 return true; 262 } 263 264 void innerRun() { 265 if (!compareAndSetState(0, RUNNING)) 266 return; 267 try { 268 runner = Thread.currentThread(); 269 innerSet(callable.call()); 270 } catch(Throwable ex) { 271 innerSetException(ex); 272 } 273 } 274 275 boolean innerRunAndReset() { 276 if (!compareAndSetState(0, RUNNING)) 277 return false; 278 try { 279 runner = Thread.currentThread(); 280 callable.call(); runner = null; 282 return compareAndSetState(RUNNING, 0); 283 } catch(Throwable ex) { 284 innerSetException(ex); 285 return false; 286 } 287 } 288 } 289 } 290 | Popular Tags |