--- jsr166/src/jsr166e/ForkJoinWorkerThread.java 2012/11/14 17:20:29 1.2 +++ jsr166/src/jsr166e/ForkJoinWorkerThread.java 2015/01/18 20:17:33 1.6 @@ -14,8 +14,8 @@ package jsr166e; * scheduling or execution. However, you can override initialization * and termination methods surrounding the main task processing loop. * If you do create such a subclass, you will also need to supply a - * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to use it - * in a {@code ForkJoinPool}. + * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to + * {@linkplain ForkJoinPool#ForkJoinPool use it} in a {@code ForkJoinPool}. * * @since 1.7 * @author Doug Lea @@ -25,17 +25,17 @@ public class ForkJoinWorkerThread extend * ForkJoinWorkerThreads are managed by ForkJoinPools and perform * ForkJoinTasks. For explanation, see the internal documentation * of class ForkJoinPool. + * + * This class just maintains links to its pool and WorkQueue. The + * pool field is set immediately upon construction, but the + * workQueue field is not set until a call to registerWorker + * completes. This leads to a visibility race, that is tolerated + * by requiring that the workQueue field is only accessed by the + * owning thread. */ - final ForkJoinPool.WorkQueue workQueue; // Work-stealing mechanics final ForkJoinPool pool; // the pool this thread works in - - /** - * An initial name for a newly constructed worker, used until - * onStart can establish a useful name. This removes need to - * establish a name from worker startup path. - */ - static final String provisionalName = "aForkJoinWorkerThread"; + final ForkJoinPool.WorkQueue workQueue; // work-stealing mechanics /** * Creates a ForkJoinWorkerThread operating in the given pool. @@ -44,14 +44,10 @@ public class ForkJoinWorkerThread extend * @throws NullPointerException if pool is null */ protected ForkJoinWorkerThread(ForkJoinPool pool) { - super(provisionalName); // bootstrap name - Thread.UncaughtExceptionHandler ueh = pool.ueh; - if (ueh != null) - setUncaughtExceptionHandler(ueh); - setDaemon(true); + // Use a placeholder until a useful name can be set in registerWorker + super("aForkJoinWorkerThread"); this.pool = pool; - pool.registerWorker(this.workQueue = new ForkJoinPool.WorkQueue - (pool, this, pool.localMode)); + this.workQueue = pool.registerWorker(this); } /** @@ -64,16 +60,17 @@ public class ForkJoinWorkerThread extend } /** - * Returns the index number of this thread in its pool. The - * returned value ranges from zero to the maximum number of - * threads (minus one) that have ever been created in the pool. - * This method may be useful for applications that track status or - * collect results per-worker rather than per-task. + * Returns the unique index number of this thread in its pool. + * The returned value ranges from zero to the maximum number of + * threads (minus one) that may exist in the pool, and does not + * change during the lifetime of the thread. This method may be + * useful for applications that track status or collect results + * per-worker-thread rather than per-task. * * @return the index number */ public int getPoolIndex() { - return workQueue.poolIndex; + return workQueue.poolIndex >>> 1; // ignore odd/even tag bit } /** @@ -86,10 +83,6 @@ public class ForkJoinWorkerThread extend * processing tasks. */ protected void onStart() { - String pref; // replace bootstrap name - if (provisionalName.equals(getName()) && - (pref = pool.workerNamePrefix) != null) - setName(pref.concat(Long.toString(getId()))); } /**