--- jsr166/src/jsr166e/CompletableFuture.java 2013/01/03 07:01:49 1.4 +++ jsr166/src/jsr166e/CompletableFuture.java 2013/05/20 16:16:42 1.17 @@ -55,7 +55,7 @@ import java.util.concurrent.locks.LockSu * Executor} or by default the {@link ForkJoinPool#commonPool()}, of a * function or action that will result in the completion of a new * CompletableFuture. To simplify monitoring, debugging, and tracking, - * all generated asynchronous tasks are instances of the tagging + * all generated asynchronous tasks are instances of the marker * interface {@link AsynchronousCompletionTask}. * *

jsr166e note: During transition, this class @@ -83,9 +83,9 @@ public class CompletableFuture implem /* * Overview: * - * 1. Non-nullness of field result (set via CAS) indicates - * done. An AltResult is used to box null as a result, as well as - * to hold exceptions. Using a single field makes completion fast + * 1. Non-nullness of field result (set via CAS) indicates done. + * An AltResult is used to box null as a result, as well as to + * hold exceptions. Using a single field makes completion fast * and simple to detect and trigger, at the expense of a lot of * encoding and decoding that infiltrates many methods. One minor * simplification relies on the (static) NIL (to box null results) @@ -380,7 +380,7 @@ public class CompletableFuture implem /* ------------- Async tasks -------------- */ /** - * A tagging interface identifying asynchronous tasks produced by + * A marker interface identifying asynchronous tasks produced by * {@code async} methods. This may be useful for monitoring, * debugging, and tracking asynchronous activities. */ @@ -388,7 +388,7 @@ public class CompletableFuture implem } /** Base class can act as either FJ or plain Runnable */ - static abstract class Async extends ForkJoinTask + abstract static class Async extends ForkJoinTask implements Runnable, AsynchronousCompletionTask { public final Void getRawResult() { return null; } public final void setRawResult(Void v) { } @@ -557,7 +557,7 @@ public class CompletableFuture implem } // Opportunistically subclass AtomicInteger to use compareAndSet to claim. - static abstract class Completion extends AtomicInteger implements Runnable { + abstract static class Completion extends AtomicInteger implements Runnable { } static final class ApplyCompletion extends Completion { @@ -1053,7 +1053,7 @@ public class CompletableFuture implem (r = a.result) != null && compareAndSet(0, 1)) { if ((r instanceof AltResult) && - (ex = ((AltResult)r).ex) != null) { + (ex = ((AltResult)r).ex) != null) { try { t = fn.apply(ex); } catch (Throwable rex) { @@ -1319,19 +1319,18 @@ public class CompletableFuture implem Object r; Throwable ex, cause; if ((r = result) == null && (r = waitingGet(true)) == null) throw new InterruptedException(); - if (r instanceof AltResult) { - if ((ex = ((AltResult)r).ex) != null) { - if (ex instanceof CancellationException) - throw (CancellationException)ex; - if ((ex instanceof CompletionException) && - (cause = ex.getCause()) != null) - ex = cause; - throw new ExecutionException(ex); - } - return null; + if (!(r instanceof AltResult)) { + @SuppressWarnings("unchecked") T tr = (T) r; + return tr; } - @SuppressWarnings("unchecked") T tr = (T) r; - return tr; + if ((ex = ((AltResult)r).ex) == null) + return null; + if (ex instanceof CancellationException) + throw (CancellationException)ex; + if ((ex instanceof CompletionException) && + (cause = ex.getCause()) != null) + ex = cause; + throw new ExecutionException(ex); } /** @@ -1356,19 +1355,18 @@ public class CompletableFuture implem throw new InterruptedException(); if ((r = result) == null) r = timedAwaitDone(nanos); - if (r instanceof AltResult) { - if ((ex = ((AltResult)r).ex) != null) { - if (ex instanceof CancellationException) - throw (CancellationException)ex; - if ((ex instanceof CompletionException) && - (cause = ex.getCause()) != null) - ex = cause; - throw new ExecutionException(ex); - } - return null; + if (!(r instanceof AltResult)) { + @SuppressWarnings("unchecked") T tr = (T) r; + return tr; } - @SuppressWarnings("unchecked") T tr = (T) r; - return tr; + if ((ex = ((AltResult)r).ex) == null) + return null; + if (ex instanceof CancellationException) + throw (CancellationException)ex; + if ((ex instanceof CompletionException) && + (cause = ex.getCause()) != null) + ex = cause; + throw new ExecutionException(ex); } /** @@ -1389,18 +1387,17 @@ public class CompletableFuture implem Object r; Throwable ex; if ((r = result) == null) r = waitingGet(false); - if (r instanceof AltResult) { - if ((ex = ((AltResult)r).ex) != null) { - if (ex instanceof CancellationException) - throw (CancellationException)ex; - if (ex instanceof CompletionException) - throw (CompletionException)ex; - throw new CompletionException(ex); - } - return null; + if (!(r instanceof AltResult)) { + @SuppressWarnings("unchecked") T tr = (T) r; + return tr; } - @SuppressWarnings("unchecked") T tr = (T) r; - return tr; + if ((ex = ((AltResult)r).ex) == null) + return null; + if (ex instanceof CancellationException) + throw (CancellationException)ex; + if (ex instanceof CompletionException) + throw (CompletionException)ex; + throw new CompletionException(ex); } /** @@ -1417,18 +1414,17 @@ public class CompletableFuture implem Object r; Throwable ex; if ((r = result) == null) return valueIfAbsent; - if (r instanceof AltResult) { - if ((ex = ((AltResult)r).ex) != null) { - if (ex instanceof CancellationException) - throw (CancellationException)ex; - if (ex instanceof CompletionException) - throw (CompletionException)ex; - throw new CompletionException(ex); - } - return null; + if (!(r instanceof AltResult)) { + @SuppressWarnings("unchecked") T tr = (T) r; + return tr; } - @SuppressWarnings("unchecked") T tr = (T) r; - return tr; + if ((ex = ((AltResult)r).ex) == null) + return null; + if (ex instanceof CancellationException) + throw (CancellationException)ex; + if (ex instanceof CompletionException) + throw (CompletionException)ex; + throw new CompletionException(ex); } /** @@ -1792,7 +1788,6 @@ public class CompletableFuture implem * @param executor the executor to use for asynchronous execution * @return the new CompletableFuture */ - public CompletableFuture thenCombineAsync(CompletableFuture other, BiFun fn, Executor executor) { @@ -2449,10 +2444,10 @@ public class CompletableFuture implem * then the returned CompletableFuture also does so, with a * CompletionException holding this exception as its cause. * - * @param fn the function returning a new CompletableFuture. + * @param fn the function returning a new CompletableFuture * @return the CompletableFuture, that {@code isDone()} upon * return if completed by the given function, or an exception - * occurs. + * occurs */ public CompletableFuture thenCompose(Fun> fn) { @@ -2531,7 +2526,7 @@ public class CompletableFuture implem if (r != null && (d == null || d.compareAndSet(0, 1))) { T t = null; Throwable ex, dx = null; if (r instanceof AltResult) { - if ((ex = ((AltResult)r).ex) != null) { + if ((ex = ((AltResult)r).ex) != null) { try { t = fn.apply(ex); } catch (Throwable rex) { @@ -2559,7 +2554,6 @@ public class CompletableFuture implem * * @param fn the function to use to compute the value of the * returned CompletableFuture - * @return the new CompletableFuture */ public CompletableFuture handle(BiFun fn) { @@ -2633,17 +2627,16 @@ public class CompletableFuture implem */ public boolean isCancelled() { Object r; - return ((r = result) != null && - (r instanceof AltResult) && - (((AltResult)r).ex instanceof CancellationException)); + return ((r = result) instanceof AltResult) && + (((AltResult)r).ex instanceof CancellationException); } /** * Forcibly sets or resets the value subsequently returned by - * method get() and related methods, whether or not already - * completed. This method is designed for use only in error - * recovery actions, and even in such situations may result in - * ongoing dependent completions using established versus + * method {@link #get()} and related methods, whether or not + * already completed. This method is designed for use only in + * error recovery actions, and even in such situations may result + * in ongoing dependent completions using established versus * overwritten outcomes. * * @param value the completion value @@ -2654,9 +2647,9 @@ public class CompletableFuture implem } /** - * Forcibly causes subsequent invocations of method get() and - * related methods to throw the given exception, whether or not - * already completed. This method is designed for use only in + * Forcibly causes subsequent invocations of method {@link #get()} + * and related methods to throw the given exception, whether or + * not already completed. This method is designed for use only in * recovery actions, and even in such situations may result in * ongoing dependent completions using established versus * overwritten outcomes. @@ -2700,22 +2693,23 @@ public class CompletableFuture implem private static sun.misc.Unsafe getUnsafe() { try { return sun.misc.Unsafe.getUnsafe(); - } catch (SecurityException se) { - try { - return java.security.AccessController.doPrivileged - (new java.security - .PrivilegedExceptionAction() { - public sun.misc.Unsafe run() throws Exception { - java.lang.reflect.Field f = sun.misc - .Unsafe.class.getDeclaredField("theUnsafe"); - f.setAccessible(true); - return (sun.misc.Unsafe) f.get(null); - }}); - } catch (java.security.PrivilegedActionException e) { - throw new RuntimeException("Could not initialize intrinsics", - e.getCause()); - } + } catch (SecurityException tryReflectionInstead) {} + try { + return java.security.AccessController.doPrivileged + (new java.security.PrivilegedExceptionAction() { + public sun.misc.Unsafe run() throws Exception { + Class k = sun.misc.Unsafe.class; + for (java.lang.reflect.Field f : k.getDeclaredFields()) { + f.setAccessible(true); + Object x = f.get(null); + if (k.isInstance(x)) + return k.cast(x); + } + throw new NoSuchFieldError("the Unsafe"); + }}); + } catch (java.security.PrivilegedActionException e) { + throw new RuntimeException("Could not initialize intrinsics", + e.getCause()); } } - }