--- jsr166/src/jsr166y/ForkJoinTask.java 2013/01/01 15:10:39 1.98 +++ jsr166/src/jsr166y/ForkJoinTask.java 2016/06/30 14:17:04 1.104 @@ -71,7 +71,7 @@ import java.lang.reflect.Constructor; * encountering the exception; minimally only the latter. * *

It is possible to define and use ForkJoinTasks that may block, - * but doing do requires three further considerations: (1) Completion + * but doing so requires three further considerations: (1) Completion * of few if any other tasks should be dependent on a task * that blocks on external synchronization or I/O. Event-style async * tasks that are never joined (for example, those subclassing {@link @@ -395,11 +395,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); } } @@ -468,7 +470,7 @@ public abstract class ForkJoinTask im } /** - * Removes exception node and clears status + * Removes exception node and clears status. */ private void clearExceptionalCompletion() { int h = System.identityHashCode(this); @@ -561,9 +563,9 @@ public abstract class ForkJoinTask im 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) { @@ -1065,10 +1067,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; @@ -1326,7 +1328,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. */ @@ -1347,7 +1349,7 @@ public abstract class ForkJoinTask im } /** - * Adaptor for Runnables without results + * Adapter for Runnables without results */ static final class AdaptedRunnableAction extends ForkJoinTask implements RunnableFuture { @@ -1364,7 +1366,7 @@ public abstract class ForkJoinTask im } /** - * Adaptor for Callables + * Adapter for Callables */ static final class AdaptedCallable extends ForkJoinTask implements RunnableFuture { @@ -1485,22 +1487,23 @@ public abstract class ForkJoinTask im 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()); } } - }