I contacted Doug Lea about the thread pool idea, and he thought this was
a "good plan". He also said:
- "To maximize ease of changeover to 1.5, you could temporarily
add a
- small 'Executors' class with factory method newFixedThreadPool(int
- nthreads) that creates a PooledExecutor. If you used this for all
- thread pools then later, you could kill that class, and instead
import
- the java.util.concurrent version.
- "(See the source and javadoc for Executors class for more
details.
- http://gee.cs.oswego.edu/dl/concurrency-interest/index.html)"
The class Executors, from the cited source is:
- /*
- * 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.AccessControlException;
- /**
- * Factory and utility methods for [EMAIL PROTECTED] Executor}, [EMAIL PROTECTED]
- * ExecutorService}, [EMAIL PROTECTED] ScheduledExecutorService}, [EMAIL PROTECTED]
- * ThreadFactory}, and [EMAIL PROTECTED] Callable} classes defined in
this
- * package. This class supports the following kinds of
methods:
- *
- * <ul>
- * <li> Methods that create and return an
[EMAIL PROTECTED] ExecutorService}
- * set up with
commonly useful configuration settings.
- * <li> Methods that create and return a
[EMAIL PROTECTED] ScheduledExecutorService}
- * set up with
commonly useful configuration settings.
- * <li> Methods that create and return a
"wrapped" ExecutorService, that
- * disables
reconfiguration by making implementation-specific methods
- * inaccessible.
- * <li> Methods that create and return a
[EMAIL PROTECTED] ThreadFactory}
- * that sets newly
created threads to a known state.
- * <li> Methods that create and return a
[EMAIL PROTECTED] Callable}
- * out of other
closure-like forms, so they can be used
- * in execution
methods requiring <tt>Callable</tt>.
- * </ul>
- *
- * @since 1.5
- * @author Doug Lea
- */
- public class Executors {
- /**
- * Creates a thread pool that reuses a fixed
set of threads
- * operating off a shared unbounded queue. 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.
- *
- * @param nThreads the number of threads in
the pool
- * @return the newly created thread pool
- */
- public static ExecutorService
newFixedThreadPool(int nThreads) {
- return new
ThreadPoolExecutor(nThreads, nThreads,
-
0L, TimeUnit.MILLISECONDS,
-
new LinkedBlockingQueue<Runnable>());
- }
- /**
- * Creates a thread pool that reuses a fixed
set of threads
- * operating off a shared unbounded queue,
using the provided
- * ThreadFactory to create new threads when
needed.
- *
- * @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
- */
- public static ExecutorService
newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
- return new
ThreadPoolExecutor(nThreads, nThreads,
-
0L, TimeUnit.MILLISECONDS,
-
new LinkedBlockingQueue<Runnable>(),
-
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
- * <tt>newFixedThreadPool(1)</tt>
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
DelegatedExecutorService
-
(new ThreadPoolExecutor(1, 1,
-
0L, TimeUnit.MILLISECONDS,
-
new LinkedBlockingQueue<Runnable>()));
- }
- /**
- * 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 <tt>newFixedThreadPool(1,
threadFactory)</tt> 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
- */
- public static ExecutorService
newSingleThreadExecutor(ThreadFactory threadFactory) {
- return new
DelegatedExecutorService
-
(new ThreadPoolExecutor(1, 1,
-
0L, TimeUnit.MILLISECONDS,
-
new LinkedBlockingQueue<Runnable>(),
-
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 <tt>execute</tt> 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 [EMAIL PROTECTED]
ThreadPoolExecutor} constructors.
- *
- * @return the newly created thread pool
- */
- public static ExecutorService
newCachedThreadPool() {
- return new
ThreadPoolExecutor(0, Integer.MAX_VALUE,
-
60L, TimeUnit.SECONDS,
-
new SynchronousQueue<Runnable>());
- }
- /**
- * 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
- */
- public static ExecutorService
newCachedThreadPool(ThreadFactory threadFactory) {
- return new
ThreadPoolExecutor(0, Integer.MAX_VALUE,
-
60L, TimeUnit.SECONDS,
-
new SynchronousQueue<Runnable>(),
-
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
- *
<tt>newScheduledThreadPool(1)</tt> 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
<tt>newScheduledThreadPool(1, threadFactory)</tt>
- * 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
- */
- 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
- */
- 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
- */
- public static ScheduledExecutorService
newScheduledThreadPool(
-
int corePoolSize, ThreadFactory threadFactory) {
- return new
ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
- }
- /**
- * Returns an object that delegates all
defined [EMAIL PROTECTED]
- * 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
<tt>ExecutorService</tt> 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 [EMAIL PROTECTED]
- * 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
<tt>ScheduledExecutorService</tt> 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 [EMAIL PROTECTED] ThreadGroup}. If there is a
[EMAIL PROTECTED]
- * java.lang.SecurityManager}, it uses the
group of [EMAIL PROTECTED]
- * System#getSecurityManager}, else the group
of the thread
- * invoking this
<tt>defaultThreadFactory</tt> method. Each new
- * thread is created as a non-daemon thread
with priority
- * <tt>Thread.NORM_PRIORITY</tt>.
New threads have names
- * accessible via [EMAIL PROTECTED] Thread#getName} of
- * <em>pool-N-thread-M</em>,
where <em>N</em> is the sequence
- * number of this factory, and
<em>M</em> is the sequence number
- * of the thread created by this factory.
- * @return a thread factory
- */
- public static ThreadFactory defaultThreadFactory()
{
- return new
DefaultThreadFactory();