diff -r fd16c54261b3 -r 90ce3da70b43 jdk/src/share/classes/java/util/concurrent/Executors.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/Executors.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,706 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedActionException;
+import java.security.AccessControlException;
+import sun.security.util.SecurityConstants;
+
+/**
+ * Factory and utility methods for {@link Executor}, {@link
+ * ExecutorService}, {@link ScheduledExecutorService}, {@link
+ * ThreadFactory}, and {@link Callable} classes defined in this
+ * package. This class supports the following kinds of methods:
+ *
+ *
+ *
Methods that create and return an {@link ExecutorService}
+ * set up with commonly useful configuration settings.
+ *
Methods that create and return a {@link ScheduledExecutorService}
+ * set up with commonly useful configuration settings.
+ *
Methods that create and return a "wrapped" ExecutorService, that
+ * disables reconfiguration by making implementation-specific methods
+ * inaccessible.
+ *
Methods that create and return a {@link ThreadFactory}
+ * that sets newly created threads to a known state.
+ *
Methods that create and return a {@link Callable}
+ * out of other closure-like forms, so they can be used
+ * in execution methods requiring Callable.
+ *
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class Executors {
+
+ /**
+ * Creates a thread pool that reuses a fixed number of threads
+ * operating off a shared unbounded queue. At any point, at most
+ * nThreads threads will be active processing tasks.
+ * If additional tasks are submitted when all threads are active,
+ * they will wait in the queue until a thread is available.
+ * If any thread terminates due to a failure during execution
+ * prior to shutdown, a new one will take its place if needed to
+ * execute subsequent tasks. The threads in the pool will exist
+ * until it is explicitly {@link ExecutorService#shutdown shutdown}.
+ *
+ * @param nThreads the number of threads in the pool
+ * @return the newly created thread pool
+ * @throws IllegalArgumentException if nThreads <= 0
+ */
+ public static ExecutorService newFixedThreadPool(int nThreads) {
+ return new ThreadPoolExecutor(nThreads, nThreads,
+ 0L, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue());
+ }
+
+ /**
+ * Creates a thread pool that reuses a fixed number of threads
+ * operating off a shared unbounded queue, using the provided
+ * ThreadFactory to create new threads when needed. At any point,
+ * at most nThreads threads will be active processing
+ * tasks. If additional tasks are submitted when all threads are
+ * active, they will wait in the queue until a thread is
+ * available. If any thread terminates due to a failure during
+ * execution prior to shutdown, a new one will take its place if
+ * needed to execute subsequent tasks. The threads in the pool will
+ * exist until it is explicitly {@link ExecutorService#shutdown
+ * shutdown}.
+ *
+ * @param nThreads the number of threads in the pool
+ * @param threadFactory the factory to use when creating new threads
+ * @return the newly created thread pool
+ * @throws NullPointerException if threadFactory is null
+ * @throws IllegalArgumentException if nThreads <= 0
+ */
+ public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
+ return new ThreadPoolExecutor(nThreads, nThreads,
+ 0L, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue(),
+ threadFactory);
+ }
+
+ /**
+ * Creates an Executor that uses a single worker thread operating
+ * off an unbounded queue. (Note however that if this single
+ * thread terminates due to a failure during execution prior to
+ * shutdown, a new one will take its place if needed to execute
+ * subsequent tasks.) Tasks are guaranteed to execute
+ * sequentially, and no more than one task will be active at any
+ * given time. Unlike the otherwise equivalent
+ * newFixedThreadPool(1) the returned executor is
+ * guaranteed not to be reconfigurable to use additional threads.
+ *
+ * @return the newly created single-threaded Executor
+ */
+ public static ExecutorService newSingleThreadExecutor() {
+ return new FinalizableDelegatedExecutorService
+ (new ThreadPoolExecutor(1, 1,
+ 0L, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue()));
+ }
+
+ /**
+ * Creates an Executor that uses a single worker thread operating
+ * off an unbounded queue, and uses the provided ThreadFactory to
+ * create a new thread when needed. Unlike the otherwise
+ * equivalent newFixedThreadPool(1, threadFactory) the
+ * returned executor is guaranteed not to be reconfigurable to use
+ * additional threads.
+ *
+ * @param threadFactory the factory to use when creating new
+ * threads
+ *
+ * @return the newly created single-threaded Executor
+ * @throws NullPointerException if threadFactory is null
+ */
+ public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
+ return new FinalizableDelegatedExecutorService
+ (new ThreadPoolExecutor(1, 1,
+ 0L, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue(),
+ threadFactory));
+ }
+
+ /**
+ * Creates a thread pool that creates new threads as needed, but
+ * will reuse previously constructed threads when they are
+ * available. These pools will typically improve the performance
+ * of programs that execute many short-lived asynchronous tasks.
+ * Calls to execute will reuse previously constructed
+ * threads if available. If no existing thread is available, a new
+ * thread will be created and added to the pool. Threads that have
+ * not been used for sixty seconds are terminated and removed from
+ * the cache. Thus, a pool that remains idle for long enough will
+ * not consume any resources. Note that pools with similar
+ * properties but different details (for example, timeout parameters)
+ * may be created using {@link ThreadPoolExecutor} constructors.
+ *
+ * @return the newly created thread pool
+ */
+ public static ExecutorService newCachedThreadPool() {
+ return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
+ 60L, TimeUnit.SECONDS,
+ new SynchronousQueue());
+ }
+
+ /**
+ * Creates a thread pool that creates new threads as needed, but
+ * will reuse previously constructed threads when they are
+ * available, and uses the provided
+ * ThreadFactory to create new threads when needed.
+ * @param threadFactory the factory to use when creating new threads
+ * @return the newly created thread pool
+ * @throws NullPointerException if threadFactory is null
+ */
+ public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
+ return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
+ 60L, TimeUnit.SECONDS,
+ new SynchronousQueue(),
+ threadFactory);
+ }
+
+ /**
+ * Creates a single-threaded executor that can schedule commands
+ * to run after a given delay, or to execute periodically.
+ * (Note however that if this single
+ * thread terminates due to a failure during execution prior to
+ * shutdown, a new one will take its place if needed to execute
+ * subsequent tasks.) Tasks are guaranteed to execute
+ * sequentially, and no more than one task will be active at any
+ * given time. Unlike the otherwise equivalent
+ * newScheduledThreadPool(1) the returned executor is
+ * guaranteed not to be reconfigurable to use additional threads.
+ * @return the newly created scheduled executor
+ */
+ public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
+ return new DelegatedScheduledExecutorService
+ (new ScheduledThreadPoolExecutor(1));
+ }
+
+ /**
+ * Creates a single-threaded executor that can schedule commands
+ * to run after a given delay, or to execute periodically. (Note
+ * however that if this single thread terminates due to a failure
+ * during execution prior to shutdown, a new one will take its
+ * place if needed to execute subsequent tasks.) Tasks are
+ * guaranteed to execute sequentially, and no more than one task
+ * will be active at any given time. Unlike the otherwise
+ * equivalent newScheduledThreadPool(1, threadFactory)
+ * the returned executor is guaranteed not to be reconfigurable to
+ * use additional threads.
+ * @param threadFactory the factory to use when creating new
+ * threads
+ * @return a newly created scheduled executor
+ * @throws NullPointerException if threadFactory is null
+ */
+ public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
+ return new DelegatedScheduledExecutorService
+ (new ScheduledThreadPoolExecutor(1, threadFactory));
+ }
+
+ /**
+ * Creates a thread pool that can schedule commands to run after a
+ * given delay, or to execute periodically.
+ * @param corePoolSize the number of threads to keep in the pool,
+ * even if they are idle.
+ * @return a newly created scheduled thread pool
+ * @throws IllegalArgumentException if corePoolSize < 0
+ */
+ public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
+ return new ScheduledThreadPoolExecutor(corePoolSize);
+ }
+
+ /**
+ * Creates a thread pool that can schedule commands to run after a
+ * given delay, or to execute periodically.
+ * @param corePoolSize the number of threads to keep in the pool,
+ * even if they are idle.
+ * @param threadFactory the factory to use when the executor
+ * creates a new thread.
+ * @return a newly created scheduled thread pool
+ * @throws IllegalArgumentException if corePoolSize < 0
+ * @throws NullPointerException if threadFactory is null
+ */
+ public static ScheduledExecutorService newScheduledThreadPool(
+ int corePoolSize, ThreadFactory threadFactory) {
+ return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
+ }
+
+
+ /**
+ * Returns an object that delegates all defined {@link
+ * ExecutorService} methods to the given executor, but not any
+ * other methods that might otherwise be accessible using
+ * casts. This provides a way to safely "freeze" configuration and
+ * disallow tuning of a given concrete implementation.
+ * @param executor the underlying implementation
+ * @return an ExecutorService instance
+ * @throws NullPointerException if executor null
+ */
+ public static ExecutorService unconfigurableExecutorService(ExecutorService executor) {
+ if (executor == null)
+ throw new NullPointerException();
+ return new DelegatedExecutorService(executor);
+ }
+
+ /**
+ * Returns an object that delegates all defined {@link
+ * ScheduledExecutorService} methods to the given executor, but
+ * not any other methods that might otherwise be accessible using
+ * casts. This provides a way to safely "freeze" configuration and
+ * disallow tuning of a given concrete implementation.
+ * @param executor the underlying implementation
+ * @return a ScheduledExecutorService instance
+ * @throws NullPointerException if executor null
+ */
+ public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) {
+ if (executor == null)
+ throw new NullPointerException();
+ return new DelegatedScheduledExecutorService(executor);
+ }
+
+ /**
+ * Returns a default thread factory used to create new threads.
+ * This factory creates all new threads used by an Executor in the
+ * same {@link ThreadGroup}. If there is a {@link
+ * java.lang.SecurityManager}, it uses the group of {@link
+ * System#getSecurityManager}, else the group of the thread
+ * invoking this defaultThreadFactory method. Each new
+ * thread is created as a non-daemon thread with priority set to
+ * the smaller of Thread.NORM_PRIORITY and the maximum
+ * priority permitted in the thread group. New threads have names
+ * accessible via {@link Thread#getName} of
+ * pool-N-thread-M, where N is the sequence
+ * number of this factory, and M is the sequence number
+ * of the thread created by this factory.
+ * @return a thread factory
+ */
+ public static ThreadFactory defaultThreadFactory() {
+ return new DefaultThreadFactory();
+ }
+
+ /**
+ * Returns a thread factory used to create new threads that
+ * have the same permissions as the current thread.
+ * This factory creates threads with the same settings as {@link
+ * Executors#defaultThreadFactory}, additionally setting the
+ * AccessControlContext and contextClassLoader of new threads to
+ * be the same as the thread invoking this
+ * privilegedThreadFactory method. A new
+ * privilegedThreadFactory can be created within an
+ * {@link AccessController#doPrivileged} action setting the
+ * current thread's access control context to create threads with
+ * the selected permission settings holding within that action.
+ *
+ *
Note that while tasks running within such threads will have
+ * the same access control and class loader settings as the
+ * current thread, they need not have the same {@link
+ * java.lang.ThreadLocal} or {@link
+ * java.lang.InheritableThreadLocal} values. If necessary,
+ * particular values of thread locals can be set or reset before
+ * any task runs in {@link ThreadPoolExecutor} subclasses using
+ * {@link ThreadPoolExecutor#beforeExecute}. Also, if it is
+ * necessary to initialize worker threads to have the same
+ * InheritableThreadLocal settings as some other designated
+ * thread, you can create a custom ThreadFactory in which that
+ * thread waits for and services requests to create others that
+ * will inherit its values.
+ *
+ * @return a thread factory
+ * @throws AccessControlException if the current access control
+ * context does not have permission to both get and set context
+ * class loader.
+ */
+ public static ThreadFactory privilegedThreadFactory() {
+ return new PrivilegedThreadFactory();
+ }
+
+ /**
+ * Returns a {@link Callable} object that, when
+ * called, runs the given task and returns the given result. This
+ * can be useful when applying methods requiring a
+ * Callable to an otherwise resultless action.
+ * @param task the task to run
+ * @param result the result to return
+ * @return a callable object
+ * @throws NullPointerException if task null
+ */
+ public static Callable callable(Runnable task, T result) {
+ if (task == null)
+ throw new NullPointerException();
+ return new RunnableAdapter(task, result);
+ }
+
+ /**
+ * Returns a {@link Callable} object that, when
+ * called, runs the given task and returns null.
+ * @param task the task to run
+ * @return a callable object
+ * @throws NullPointerException if task null
+ */
+ public static Callable