--- jsr166/src/jsr166e/ForkJoinTask.java 2013/07/22 16:52:31 1.15 +++ jsr166/src/jsr166e/ForkJoinTask.java 2015/10/13 19:45:34 1.18 @@ -411,11 +411,13 @@ public abstract class ForkJoinTask im final Throwable ex; ExceptionNode next; final long thrower; // use id not ref to avoid weak cycles + final int hashCode; // store task hashCode before weak ref disappears ExceptionNode(ForkJoinTask task, Throwable ex, ExceptionNode next) { super(task, exceptionTableRefQueue); this.ex = ex; this.next = next; this.thrower = Thread.currentThread().getId(); + this.hashCode = System.identityHashCode(task); } } @@ -574,12 +576,15 @@ public abstract class ForkJoinTask im /** * Poll stale refs and remove them. Call only while holding lock. */ + /** + * Poll stale refs and remove them. Call only while holding lock. + */ private static void expungeStaleExceptions() { for (Object x; (x = exceptionTableRefQueue.poll()) != null;) { if (x instanceof ExceptionNode) { - ForkJoinTask key = ((ExceptionNode)x).get(); + int hashCode = ((ExceptionNode)x).hashCode; ExceptionNode[] t = exceptionTable; - int i = System.identityHashCode(key) & (t.length - 1); + int i = hashCode & (t.length - 1); ExceptionNode e = t[i]; ExceptionNode pred = null; while (e != null) { @@ -1081,10 +1086,10 @@ public abstract class ForkJoinTask im /** * Possibly executes tasks until the pool hosting the current task - * {@link ForkJoinPool#isQuiescent is quiescent}. This method may - * be of use in designs in which many tasks are forked, but none - * are explicitly joined, instead executing them until all are - * processed. + * {@linkplain ForkJoinPool#isQuiescent is quiescent}. This + * method may be of use in designs in which many tasks are forked, + * but none are explicitly joined, instead executing them until + * all are processed. */ public static void helpQuiesce() { Thread t; @@ -1342,7 +1347,7 @@ public abstract class ForkJoinTask im } /** - * Adaptor for Runnables. This implements RunnableFuture + * Adapter for Runnables. This implements RunnableFuture * to be compliant with AbstractExecutorService constraints * when used in ForkJoinPool. */ @@ -1363,7 +1368,7 @@ public abstract class ForkJoinTask im } /** - * Adaptor for Runnables without results + * Adapter for Runnables without results */ static final class AdaptedRunnableAction extends ForkJoinTask implements RunnableFuture { @@ -1380,7 +1385,7 @@ public abstract class ForkJoinTask im } /** - * Adaptor for Runnables in which failure forces worker exception + * Adapter for Runnables in which failure forces worker exception */ static final class RunnableExecuteAction extends ForkJoinTask { final Runnable runnable; @@ -1398,7 +1403,7 @@ public abstract class ForkJoinTask im } /** - * Adaptor for Callables + * Adapter for Callables */ static final class AdaptedCallable extends ForkJoinTask implements RunnableFuture {