--- jsr166/src/jsr166e/ForkJoinTask.java 2013/06/19 14:55:40 1.13
+++ jsr166/src/jsr166e/ForkJoinTask.java 2013/09/20 10:52:13 1.16
@@ -134,7 +134,7 @@ import java.lang.reflect.Constructor;
* (DAG). Otherwise, executions may encounter a form of deadlock as
* tasks cyclically wait for each other. However, this framework
* supports other methods and techniques (for example the use of
- * {@link Phaser}, {@link #helpQuiesce}, and {@link #complete}) that
+ * {@link java.util.concurrent.Phaser Phaser}, {@link #helpQuiesce}, and {@link #complete}) that
* may be of use in constructing custom subclasses for problems that
* are not statically structured as DAGs. To support such usages, a
* ForkJoinTask may be atomically tagged with a {@code short}
@@ -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) {
@@ -782,6 +787,7 @@ public abstract class ForkJoinTask im
* unprocessed.
*
* @param tasks the collection of tasks
+ * @param the type of the values returned from the tasks
* @return the tasks argument, to simplify usage
* @throws NullPointerException if tasks or any element are null
*/
@@ -1444,6 +1450,7 @@ public abstract class ForkJoinTask im
*
* @param runnable the runnable action
* @param result the result upon completion
+ * @param the type of the result
* @return the task
*/
public static ForkJoinTask adapt(Runnable runnable, T result) {
@@ -1457,6 +1464,7 @@ public abstract class ForkJoinTask im
* encountered into {@code RuntimeException}.
*
* @param callable the callable action
+ * @param the type of the callable's result
* @return the task
*/
public static ForkJoinTask adapt(Callable extends T> callable) {
@@ -1470,6 +1478,8 @@ public abstract class ForkJoinTask im
/**
* Saves this task to a stream (that is, serializes it).
*
+ * @param s the stream
+ * @throws java.io.IOException if an I/O error occurs
* @serialData the current run status and the exception thrown
* during execution, or {@code null} if none
*/
@@ -1481,6 +1491,10 @@ public abstract class ForkJoinTask im
/**
* Reconstitutes this task from a stream (that is, deserializes it).
+ * @param s the stream
+ * @throws ClassNotFoundException if the class of a serialized object
+ * could not be found
+ * @throws java.io.IOException if an I/O error occurs
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {