--- jsr166/src/jsr166y/ForkJoinPool.java 2009/08/01 21:17:11 1.35 +++ jsr166/src/jsr166y/ForkJoinPool.java 2009/08/03 13:01:15 1.42 @@ -21,36 +21,39 @@ import java.util.concurrent.atomic.Atomi /** * An {@link ExecutorService} for running {@link ForkJoinTask}s. - * A ForkJoinPool provides the entry point for submissions from - * non-ForkJoinTasks, as well as management and monitoring operations. - * Normally a single ForkJoinPool is used for a large number of - * submitted tasks. Otherwise, use would not usually outweigh the - * construction and bookkeeping overhead of creating a large set of - * threads. + * A {@code ForkJoinPool} provides the entry point for submissions + * from non-{@code ForkJoinTask}s, as well as management and + * monitoring operations. * - *

ForkJoinPools differ from other kinds of Executors mainly in - * that they provide work-stealing: all threads in the pool - * attempt to find and execute subtasks created by other active tasks - * (eventually blocking if none exist). This makes them efficient when - * most tasks spawn other subtasks (as do most ForkJoinTasks), as well - * as the mixed execution of some plain Runnable- or Callable- based - * activities along with ForkJoinTasks. When setting {@linkplain - * #setAsyncMode async mode}, a ForkJoinPool may also be appropriate - * for use with fine-grained tasks that are never joined. Otherwise, - * other ExecutorService implementations are typically more - * appropriate choices. + *

A {@code ForkJoinPool} differs from other kinds of {@link + * ExecutorService} mainly by virtue of employing + * work-stealing: all threads in the pool attempt to find and + * execute subtasks created by other active tasks (eventually blocking + * waiting for work if none exist). This enables efficient processing + * when most tasks spawn other subtasks (as do most {@code + * ForkJoinTask}s). A {@code ForkJoinPool} may also be used for mixed + * execution of some plain {@code Runnable}- or {@code Callable}- + * based activities along with {@code ForkJoinTask}s. When setting + * {@linkplain #setAsyncMode async mode}, a {@code ForkJoinPool} may + * also be appropriate for use with fine-grained tasks of any form + * that are never joined. Otherwise, other {@code ExecutorService} + * implementations are typically more appropriate choices. * - *

A ForkJoinPool may be constructed with a given parallelism level - * (target pool size), which it attempts to maintain by dynamically - * adding, suspending, or resuming threads, even if some tasks are - * waiting to join others. However, no such adjustments are performed - * in the face of blocked IO or other unmanaged synchronization. The - * nested {@link ManagedBlocker} interface enables extension of - * the kinds of synchronization accommodated. The target parallelism - * level may also be changed dynamically ({@link #setParallelism}) - * and thread construction can be limited using methods - * {@link #setMaximumPoolSize} and/or - * {@link #setMaintainsParallelism}. + *

A {@code ForkJoinPool} is constructed with a given target + * parallelism level; by default, equal to the number of available + * processors. Unless configured otherwise via {@link + * #setMaintainsParallelism}, the pool attempts to maintain this + * number of active (or available) threads by dynamically adding, + * suspending, or resuming internal worker threads, even if some tasks + * are waiting to join others. However, no such adjustments are + * performed in the face of blocked IO or other unmanaged + * synchronization. The nested {@link ManagedBlocker} interface + * enables extension of the kinds of synchronization accommodated. + * The target parallelism level may also be changed dynamically + * ({@link #setParallelism}). The total number of threads may be + * limited using method {@link #setMaximumPoolSize}, in which case it + * may become possible for the activities of a pool to stall due to + * the lack of available threads to process new tasks. * *

In addition to execution and lifecycle control methods, this * class provides status check methods (for example @@ -59,10 +62,28 @@ import java.util.concurrent.atomic.Atomi * {@link #toString} returns indications of pool state in a * convenient form for informal monitoring. * + *

Sample Usage. Normally a single {@code ForkJoinPool} is + * used for all parallel task execution in a program or subsystem. + * Otherwise, use would not usually outweigh the construction and + * bookkeeping overhead of creating a large set of threads. For + * example a common pool could be used for the {@code SortTasks} + * illustrated in {@link RecursiveAction}. Because {@code + * ForkJoinPool} uses threads in {@linkplain java.lang.Thread#isDaemon + * daemon} mode, there is typically no need to explictly {@link + * #shutdown} such a pool upon program exit. + * + *

+ * static final ForkJoinPool mainPool = new ForkJoinPool();
+ * ...
+ * public void sort(long[] array) {
+ *   mainPool.invoke(new SortTask(array, 0, array.length));
+ * }
+ * 
+ * *

Implementation notes: This implementation restricts the * maximum number of running threads to 32767. Attempts to create * pools with greater than the maximum result in - * IllegalArgumentExceptions. + * {@code IllegalArgumentException}. * * @since 1.7 * @author Doug Lea @@ -342,9 +363,9 @@ public class ForkJoinPool extends Abstra // Constructors /** - * Creates a ForkJoinPool with a pool size equal to the number of - * processors available on the system, using the default - * ForkJoinWorkerThreadFactory. + * Creates a {@code ForkJoinPool} with parallelism equal to {@link + * java.lang.Runtime#availableProcessors}, and using the {@linkplain + * #defaultForkJoinWorkerThreadFactory default thread factory}. * * @throws SecurityException if a security manager exists and * the caller is not permitted to modify threads @@ -357,10 +378,11 @@ public class ForkJoinPool extends Abstra } /** - * Creates a ForkJoinPool with the indicated parallelism level - * threads and using the default ForkJoinWorkerThreadFactory. + * Creates a {@code ForkJoinPool} with the indicated parallelism + * level and using the {@linkplain + * #defaultForkJoinWorkerThreadFactory default thread factory}. * - * @param parallelism the number of worker threads + * @param parallelism the parallelism level * @throws IllegalArgumentException if parallelism less than or * equal to zero * @throws SecurityException if a security manager exists and @@ -373,9 +395,9 @@ public class ForkJoinPool extends Abstra } /** - * Creates a ForkJoinPool with parallelism equal to the number of - * processors available on the system and using the given - * ForkJoinWorkerThreadFactory. + * Creates a {@code ForkJoinPool} with parallelism equal to {@link + * java.lang.Runtime#availableProcessors}, and using the given + * thread factory. * * @param factory the factory for creating new threads * @throws NullPointerException if factory is null @@ -389,9 +411,10 @@ public class ForkJoinPool extends Abstra } /** - * Creates a ForkJoinPool with the given parallelism and factory. + * Creates a {@code ForkJoinPool} with the given parallelism and + * thread factory. * - * @param parallelism the targeted number of worker threads + * @param parallelism the parallelism level * @param factory the factory for creating new threads * @throws IllegalArgumentException if parallelism less than or * equal to zero, or greater than implementation limit @@ -423,7 +446,7 @@ public class ForkJoinPool extends Abstra * Creates a new worker thread using factory. * * @param index the index to assign worker - * @return new worker, or null of factory failed + * @return new worker, or null if factory failed */ private ForkJoinWorkerThread createWorker(int index) { Thread.UncaughtExceptionHandler h = ueh; @@ -444,8 +467,16 @@ public class ForkJoinPool extends Abstra * Currently requires size to be a power of two. */ private static int arraySizeFor(int poolSize) { - return (poolSize <= 1) ? 1 : - (1 << (32 - Integer.numberOfLeadingZeros(poolSize-1))); + if (poolSize <= 1) + return 1; + // See Hackers Delight, sec 3.2 + int c = poolSize >= MAX_THREADS ? MAX_THREADS : (poolSize - 1); + c |= c >>> 1; + c |= c >>> 2; + c |= c >>> 4; + c |= c >>> 8; + c |= c >>> 16; + return c + 1; } /** @@ -578,7 +609,7 @@ public class ForkJoinPool extends Abstra * @throws NullPointerException if task is null * @throws RejectedExecutionException if pool is shut down */ - public void execute(ForkJoinTask task) { + public void execute(ForkJoinTask task) { doSubmit(task); } @@ -736,7 +767,7 @@ public class ForkJoinPool extends Abstra final ReentrantLock lock = this.workerLock; lock.lock(); try { - if (!isTerminating()) { + if (isProcessingTasks()) { int p = this.parallelism; this.parallelism = parallelism; if (parallelism > p) @@ -751,9 +782,9 @@ public class ForkJoinPool extends Abstra } /** - * Returns the targeted number of worker threads in this pool. + * Returns the targeted parallelism level of this pool. * - * @return the targeted number of worker threads in this pool + * @return the targeted parallelism level of this pool */ public int getParallelism() { return parallelism; @@ -773,7 +804,9 @@ public class ForkJoinPool extends Abstra /** * Returns the maximum number of threads allowed to exist in the - * pool, even if there are insufficient unblocked running threads. + * pool. Unless set using {@link #setMaximumPoolSize}, the + * maximum is an implementation-defined value designed only to + * prevent runaway growth. * * @return the maximum */ @@ -783,11 +816,10 @@ public class ForkJoinPool extends Abstra /** * Sets the maximum number of threads allowed to exist in the - * pool, even if there are insufficient unblocked running threads. - * Setting this value has no effect on current pool size. It - * controls construction of new threads. + * pool. Setting this value has no effect on current pool + * size. It controls construction of new threads. * - * @throws IllegalArgumentException if negative or greater then + * @throws IllegalArgumentException if negative or greater than * internal implementation limit */ public void setMaximumPoolSize(int newMax) { @@ -955,8 +987,8 @@ public class ForkJoinPool extends Abstra } /** - * Returns an estimate of the number tasks submitted to this pool - * that have not yet begun executing. This method takes time + * Returns an estimate of the number of tasks submitted to this + * pool that have not yet begun executing. This method takes time * proportional to the number of submissions. * * @return the number of queued submissions @@ -990,8 +1022,8 @@ public class ForkJoinPool extends Abstra * Removes all available unexecuted submitted and forked tasks * from scheduling queues and adds them to the given collection, * without altering their execution status. These may include - * artificially generated or wrapped tasks. This method is designed - * to be invoked only when the pool is known to be + * artificially generated or wrapped tasks. This method is + * designed to be invoked only when the pool is known to be * quiescent. Invocations at other times may not remove all * tasks. A failure encountered while attempting to add elements * to collection {@code c} may result in elements being in @@ -1088,14 +1120,14 @@ public class ForkJoinPool extends Abstra } /** - * Attempts to stop all actively executing tasks, and cancels all - * waiting tasks. Tasks that are in the process of being - * submitted or executed concurrently during the course of this - * method may or may not be rejected. Unlike some other executors, - * this method cancels rather than collects non-executed tasks - * upon termination, so always returns an empty list. However, you - * can use method {@link #drainTasksTo} before invoking this - * method to transfer unexecuted tasks to another collection. + * Attempts to cancel and/or stop all tasks, and reject all + * subsequently submitted tasks. Tasks that are in the process of + * being submitted or executed concurrently during the course of + * this method may or may not be rejected. This method cancels + * both existing and unexecuted tasks, in order to permit + * termination in the presence of task dependencies. So the method + * always returns an empty list (unlike the case for some other + * Executors). * * @return an empty list * @throws SecurityException if a security manager exists and @@ -1120,12 +1152,16 @@ public class ForkJoinPool extends Abstra /** * Returns {@code true} if the process of termination has - * commenced but possibly not yet completed. + * commenced but not yet completed. This method may be useful for + * debugging. A return of {@code true} reported a sufficient + * period after shutdown may indicate that submitted tasks have + * ignored or suppressed interruption, causing this executor not + * to properly terminate. * - * @return {@code true} if terminating + * @return {@code true} if terminating but not yet terminated */ public boolean isTerminating() { - return runStateOf(runControl) >= TERMINATING; + return runStateOf(runControl) == TERMINATING; } /** @@ -1138,6 +1174,14 @@ public class ForkJoinPool extends Abstra } /** + * Returns true if pool is not terminating or terminated. + * Used internally to suppress execution when terminating. + */ + final boolean isProcessingTasks() { + return runStateOf(runControl) < TERMINATING; + } + + /** * Blocks until all tasks have completed execution after a shutdown * request, or the timeout occurs, or the current thread is * interrupted, whichever happens first. @@ -1191,7 +1235,7 @@ public class ForkJoinPool extends Abstra transitionRunStateTo(TERMINATED); termination.signalAll(); } - else if (!isTerminating()) { + else if (isProcessingTasks()) { tryShrinkWorkerArray(); tryResumeSpare(true); // allow replacement } @@ -1432,7 +1476,7 @@ public class ForkJoinPool extends Abstra final void sync(ForkJoinWorkerThread w) { updateStealCount(w); // Transfer w's count while it is idle - while (!w.isShutdown() && !isTerminating() && !suspendIfSpare(w)) { + while (!w.isShutdown() && isProcessingTasks() && !suspendIfSpare(w)) { long prev = w.lastEventCount; WaitQueueNode node = null; WaitQueueNode h; @@ -1637,7 +1681,7 @@ public class ForkJoinPool extends Abstra for (k = 0; k < len && ws[k] != null; ++k) ; } - if (k < len && !isTerminating() && (w = createWorker(k)) != null) { + if (k < len && isProcessingTasks() && (w = createWorker(k)) != null) { ws[k] = w; w.start(); } @@ -1741,7 +1785,7 @@ public class ForkJoinPool extends Abstra * Method {@code isReleasable} must return {@code true} if * blocking is not necessary. Method {@code block} blocks the * current thread if necessary (perhaps internally invoking - * {@code isReleasable} before actually blocking.). + * {@code isReleasable} before actually blocking). * *

For example, here is a ManagedBlocker based on a * ReentrantLock: @@ -1780,25 +1824,27 @@ public class ForkJoinPool extends Abstra /** * Blocks in accord with the given blocker. If the current thread - * is a ForkJoinWorkerThread, this method possibly arranges for a - * spare thread to be activated if necessary to ensure parallelism - * while the current thread is blocked. If - * {@code maintainParallelism} is {@code true} and the pool supports - * it ({@link #getMaintainsParallelism}), this method attempts to - * maintain the pool's nominal parallelism. Otherwise it activates - * a thread only if necessary to avoid complete starvation. This - * option may be preferable when blockages use timeouts, or are - * almost always brief. + * is a {@link ForkJoinWorkerThread}, this method possibly + * arranges for a spare thread to be activated if necessary to + * ensure parallelism while the current thread is blocked. + * + *

If {@code maintainParallelism} is {@code true} and the pool + * supports it ({@link #getMaintainsParallelism}), this method + * attempts to maintain the pool's nominal parallelism. Otherwise + * it activates a thread only if necessary to avoid complete + * starvation. This option may be preferable when blockages use + * timeouts, or are almost always brief. * - *

If the caller is not a ForkJoinTask, this method is behaviorally - * equivalent to + *

If the caller is not a {@link ForkJoinTask}, this method is + * behaviorally equivalent to *

 {@code
      * while (!blocker.isReleasable())
      *   if (blocker.block())
      *     return;
      * }
- * If the caller is a ForkJoinTask, then the pool may first - * be expanded to ensure parallelism, and later adjusted. + * + * If the caller is a {@code ForkJoinTask}, then the pool may + * first be expanded to ensure parallelism, and later adjusted. * * @param blocker the blocker * @param maintainParallelism if {@code true} and supported by