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