• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Written by Doug Lea with assistance from members of JCP JSR-166
3  * Expert Group and released to the public domain, as explained at
4  * http://creativecommons.org/publicdomain/zero/1.0/
5  */
6 
7 package java.util.concurrent;
8 import java.util.*;
9 import java.util.concurrent.atomic.AtomicInteger;
10 import java.security.AccessControlContext;
11 import java.security.AccessController;
12 import java.security.PrivilegedAction;
13 import java.security.PrivilegedExceptionAction;
14 import java.security.PrivilegedActionException;
15 
16 // BEGIN android-note
17 // removed security manager docs
18 // END android-note
19 /**
20  * Factory and utility methods for {@link Executor}, {@link
21  * ExecutorService}, {@link ScheduledExecutorService}, {@link
22  * ThreadFactory}, and {@link Callable} classes defined in this
23  * package. This class supports the following kinds of methods:
24  *
25  * <ul>
26  *   <li> Methods that create and return an {@link ExecutorService}
27  *        set up with commonly useful configuration settings.
28  *   <li> Methods that create and return a {@link ScheduledExecutorService}
29  *        set up with commonly useful configuration settings.
30  *   <li> Methods that create and return a "wrapped" ExecutorService, that
31  *        disables reconfiguration by making implementation-specific methods
32  *        inaccessible.
33  *   <li> Methods that create and return a {@link ThreadFactory}
34  *        that sets newly created threads to a known state.
35  *   <li> Methods that create and return a {@link Callable}
36  *        out of other closure-like forms, so they can be used
37  *        in execution methods requiring <tt>Callable</tt>.
38  * </ul>
39  *
40  * @since 1.5
41  * @author Doug Lea
42  */
43 public class Executors {
44 
45     /**
46      * Creates a thread pool that reuses a fixed number of threads
47      * operating off a shared unbounded queue.  At any point, at most
48      * <tt>nThreads</tt> threads will be active processing tasks.
49      * If additional tasks are submitted when all threads are active,
50      * they will wait in the queue until a thread is available.
51      * If any thread terminates due to a failure during execution
52      * prior to shutdown, a new one will take its place if needed to
53      * execute subsequent tasks.  The threads in the pool will exist
54      * until it is explicitly {@link ExecutorService#shutdown shutdown}.
55      *
56      * @param nThreads the number of threads in the pool
57      * @return the newly created thread pool
58      * @throws IllegalArgumentException if {@code nThreads <= 0}
59      */
newFixedThreadPool(int nThreads)60     public static ExecutorService newFixedThreadPool(int nThreads) {
61         return new ThreadPoolExecutor(nThreads, nThreads,
62                                       0L, TimeUnit.MILLISECONDS,
63                                       new LinkedBlockingQueue<Runnable>());
64     }
65 
66     /**
67      * Creates a thread pool that reuses a fixed number of threads
68      * operating off a shared unbounded queue, using the provided
69      * ThreadFactory to create new threads when needed.  At any point,
70      * at most <tt>nThreads</tt> threads will be active processing
71      * tasks.  If additional tasks are submitted when all threads are
72      * active, they will wait in the queue until a thread is
73      * available.  If any thread terminates due to a failure during
74      * execution prior to shutdown, a new one will take its place if
75      * needed to execute subsequent tasks.  The threads in the pool will
76      * exist until it is explicitly {@link ExecutorService#shutdown
77      * shutdown}.
78      *
79      * @param nThreads the number of threads in the pool
80      * @param threadFactory the factory to use when creating new threads
81      * @return the newly created thread pool
82      * @throws NullPointerException if threadFactory is null
83      * @throws IllegalArgumentException if {@code nThreads <= 0}
84      */
newFixedThreadPool(int nThreads, ThreadFactory threadFactory)85     public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
86         return new ThreadPoolExecutor(nThreads, nThreads,
87                                       0L, TimeUnit.MILLISECONDS,
88                                       new LinkedBlockingQueue<Runnable>(),
89                                       threadFactory);
90     }
91 
92     /**
93      * Creates an Executor that uses a single worker thread operating
94      * off an unbounded queue. (Note however that if this single
95      * thread terminates due to a failure during execution prior to
96      * shutdown, a new one will take its place if needed to execute
97      * subsequent tasks.)  Tasks are guaranteed to execute
98      * sequentially, and no more than one task will be active at any
99      * given time. Unlike the otherwise equivalent
100      * <tt>newFixedThreadPool(1)</tt> the returned executor is
101      * guaranteed not to be reconfigurable to use additional threads.
102      *
103      * @return the newly created single-threaded Executor
104      */
newSingleThreadExecutor()105     public static ExecutorService newSingleThreadExecutor() {
106         return new FinalizableDelegatedExecutorService
107             (new ThreadPoolExecutor(1, 1,
108                                     0L, TimeUnit.MILLISECONDS,
109                                     new LinkedBlockingQueue<Runnable>()));
110     }
111 
112     /**
113      * Creates an Executor that uses a single worker thread operating
114      * off an unbounded queue, and uses the provided ThreadFactory to
115      * create a new thread when needed. Unlike the otherwise
116      * equivalent <tt>newFixedThreadPool(1, threadFactory)</tt> the
117      * returned executor is guaranteed not to be reconfigurable to use
118      * additional threads.
119      *
120      * @param threadFactory the factory to use when creating new
121      * threads
122      *
123      * @return the newly created single-threaded Executor
124      * @throws NullPointerException if threadFactory is null
125      */
newSingleThreadExecutor(ThreadFactory threadFactory)126     public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
127         return new FinalizableDelegatedExecutorService
128             (new ThreadPoolExecutor(1, 1,
129                                     0L, TimeUnit.MILLISECONDS,
130                                     new LinkedBlockingQueue<Runnable>(),
131                                     threadFactory));
132     }
133 
134     /**
135      * Creates a thread pool that creates new threads as needed, but
136      * will reuse previously constructed threads when they are
137      * available.  These pools will typically improve the performance
138      * of programs that execute many short-lived asynchronous tasks.
139      * Calls to <tt>execute</tt> will reuse previously constructed
140      * threads if available. If no existing thread is available, a new
141      * thread will be created and added to the pool. Threads that have
142      * not been used for sixty seconds are terminated and removed from
143      * the cache. Thus, a pool that remains idle for long enough will
144      * not consume any resources. Note that pools with similar
145      * properties but different details (for example, timeout parameters)
146      * may be created using {@link ThreadPoolExecutor} constructors.
147      *
148      * @return the newly created thread pool
149      */
newCachedThreadPool()150     public static ExecutorService newCachedThreadPool() {
151         return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
152                                       60L, TimeUnit.SECONDS,
153                                       new SynchronousQueue<Runnable>());
154     }
155 
156     /**
157      * Creates a thread pool that creates new threads as needed, but
158      * will reuse previously constructed threads when they are
159      * available, and uses the provided
160      * ThreadFactory to create new threads when needed.
161      * @param threadFactory the factory to use when creating new threads
162      * @return the newly created thread pool
163      * @throws NullPointerException if threadFactory is null
164      */
newCachedThreadPool(ThreadFactory threadFactory)165     public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
166         return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
167                                       60L, TimeUnit.SECONDS,
168                                       new SynchronousQueue<Runnable>(),
169                                       threadFactory);
170     }
171 
172     /**
173      * Creates a single-threaded executor that can schedule commands
174      * to run after a given delay, or to execute periodically.
175      * (Note however that if this single
176      * thread terminates due to a failure during execution prior to
177      * shutdown, a new one will take its place if needed to execute
178      * subsequent tasks.)  Tasks are guaranteed to execute
179      * sequentially, and no more than one task will be active at any
180      * given time. Unlike the otherwise equivalent
181      * <tt>newScheduledThreadPool(1)</tt> the returned executor is
182      * guaranteed not to be reconfigurable to use additional threads.
183      * @return the newly created scheduled executor
184      */
newSingleThreadScheduledExecutor()185     public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
186         return new DelegatedScheduledExecutorService
187             (new ScheduledThreadPoolExecutor(1));
188     }
189 
190     /**
191      * Creates a single-threaded executor that can schedule commands
192      * to run after a given delay, or to execute periodically.  (Note
193      * however that if this single thread terminates due to a failure
194      * during execution prior to shutdown, a new one will take its
195      * place if needed to execute subsequent tasks.)  Tasks are
196      * guaranteed to execute sequentially, and no more than one task
197      * will be active at any given time. Unlike the otherwise
198      * equivalent <tt>newScheduledThreadPool(1, threadFactory)</tt>
199      * the returned executor is guaranteed not to be reconfigurable to
200      * use additional threads.
201      * @param threadFactory the factory to use when creating new
202      * threads
203      * @return a newly created scheduled executor
204      * @throws NullPointerException if threadFactory is null
205      */
newSingleThreadScheduledExecutor(ThreadFactory threadFactory)206     public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
207         return new DelegatedScheduledExecutorService
208             (new ScheduledThreadPoolExecutor(1, threadFactory));
209     }
210 
211     /**
212      * Creates a thread pool that can schedule commands to run after a
213      * given delay, or to execute periodically.
214      * @param corePoolSize the number of threads to keep in the pool,
215      * even if they are idle.
216      * @return a newly created scheduled thread pool
217      * @throws IllegalArgumentException if {@code corePoolSize < 0}
218      */
newScheduledThreadPool(int corePoolSize)219     public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
220         return new ScheduledThreadPoolExecutor(corePoolSize);
221     }
222 
223     /**
224      * Creates a thread pool that can schedule commands to run after a
225      * given delay, or to execute periodically.
226      * @param corePoolSize the number of threads to keep in the pool,
227      * even if they are idle.
228      * @param threadFactory the factory to use when the executor
229      * creates a new thread.
230      * @return a newly created scheduled thread pool
231      * @throws IllegalArgumentException if {@code corePoolSize < 0}
232      * @throws NullPointerException if threadFactory is null
233      */
newScheduledThreadPool( int corePoolSize, ThreadFactory threadFactory)234     public static ScheduledExecutorService newScheduledThreadPool(
235             int corePoolSize, ThreadFactory threadFactory) {
236         return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
237     }
238 
239 
240     /**
241      * Returns an object that delegates all defined {@link
242      * ExecutorService} methods to the given executor, but not any
243      * other methods that might otherwise be accessible using
244      * casts. This provides a way to safely "freeze" configuration and
245      * disallow tuning of a given concrete implementation.
246      * @param executor the underlying implementation
247      * @return an <tt>ExecutorService</tt> instance
248      * @throws NullPointerException if executor null
249      */
unconfigurableExecutorService(ExecutorService executor)250     public static ExecutorService unconfigurableExecutorService(ExecutorService executor) {
251         if (executor == null)
252             throw new NullPointerException();
253         return new DelegatedExecutorService(executor);
254     }
255 
256     /**
257      * Returns an object that delegates all defined {@link
258      * ScheduledExecutorService} methods to the given executor, but
259      * not any other methods that might otherwise be accessible using
260      * casts. This provides a way to safely "freeze" configuration and
261      * disallow tuning of a given concrete implementation.
262      * @param executor the underlying implementation
263      * @return a <tt>ScheduledExecutorService</tt> instance
264      * @throws NullPointerException if executor null
265      */
unconfigurableScheduledExecutorService(ScheduledExecutorService executor)266     public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) {
267         if (executor == null)
268             throw new NullPointerException();
269         return new DelegatedScheduledExecutorService(executor);
270     }
271 
272     /**
273      * Returns a default thread factory used to create new threads.
274      * This factory creates all new threads used by an Executor in the
275      * same {@link ThreadGroup}. Each new
276      * thread is created as a non-daemon thread with priority set to
277      * the smaller of <tt>Thread.NORM_PRIORITY</tt> and the maximum
278      * priority permitted in the thread group.  New threads have names
279      * accessible via {@link Thread#getName} of
280      * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence
281      * number of this factory, and <em>M</em> is the sequence number
282      * of the thread created by this factory.
283      * @return a thread factory
284      */
defaultThreadFactory()285     public static ThreadFactory defaultThreadFactory() {
286         return new DefaultThreadFactory();
287     }
288 
289     /**
290      * Legacy security code; do not use.
291      */
privilegedThreadFactory()292     public static ThreadFactory privilegedThreadFactory() {
293         return new PrivilegedThreadFactory();
294     }
295 
296     /**
297      * Returns a {@link Callable} object that, when
298      * called, runs the given task and returns the given result.  This
299      * can be useful when applying methods requiring a
300      * <tt>Callable</tt> to an otherwise resultless action.
301      * @param task the task to run
302      * @param result the result to return
303      * @return a callable object
304      * @throws NullPointerException if task null
305      */
callable(Runnable task, T result)306     public static <T> Callable<T> callable(Runnable task, T result) {
307         if (task == null)
308             throw new NullPointerException();
309         return new RunnableAdapter<T>(task, result);
310     }
311 
312     /**
313      * Returns a {@link Callable} object that, when
314      * called, runs the given task and returns <tt>null</tt>.
315      * @param task the task to run
316      * @return a callable object
317      * @throws NullPointerException if task null
318      */
callable(Runnable task)319     public static Callable<Object> callable(Runnable task) {
320         if (task == null)
321             throw new NullPointerException();
322         return new RunnableAdapter<Object>(task, null);
323     }
324 
325     /**
326      * Returns a {@link Callable} object that, when
327      * called, runs the given privileged action and returns its result.
328      * @param action the privileged action to run
329      * @return a callable object
330      * @throws NullPointerException if action null
331      */
callable(final PrivilegedAction<?> action)332     public static Callable<Object> callable(final PrivilegedAction<?> action) {
333         if (action == null)
334             throw new NullPointerException();
335         return new Callable<Object>() {
336             public Object call() { return action.run(); }};
337     }
338 
339     /**
340      * Returns a {@link Callable} object that, when
341      * called, runs the given privileged exception action and returns
342      * its result.
343      * @param action the privileged exception action to run
344      * @return a callable object
345      * @throws NullPointerException if action null
346      */
347     public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) {
348         if (action == null)
349             throw new NullPointerException();
350         return new Callable<Object>() {
351             public Object call() throws Exception { return action.run(); }};
352     }
353 
354     /**
355      * Legacy security code; do not use.
356      */
357     public static <T> Callable<T> privilegedCallable(Callable<T> callable) {
358         if (callable == null)
359             throw new NullPointerException();
360         return new PrivilegedCallable<T>(callable);
361     }
362 
363     /**
364      * Returns a {@link Callable} object that will, when
365      * called, execute the given <tt>callable</tt> under the current
366      * with the current context class loader as the context class loader.
367      *
368      * @return a callable object
369      * @throws NullPointerException if callable null
370      */
371     public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) {
372         if (callable == null)
373             throw new NullPointerException();
374         return new PrivilegedCallableUsingCurrentClassLoader<T>(callable);
375     }
376 
377     // Non-public classes supporting the public methods
378 
379     /**
380      * A callable that runs given task and returns given result
381      */
382     static final class RunnableAdapter<T> implements Callable<T> {
383         final Runnable task;
384         final T result;
385         RunnableAdapter(Runnable task, T result) {
386             this.task = task;
387             this.result = result;
388         }
389         public T call() {
390             task.run();
391             return result;
392         }
393     }
394 
395     /**
396      * A callable that runs under established access control settings
397      */
398     static final class PrivilegedCallable<T> implements Callable<T> {
399         private final Callable<T> task;
400         private final AccessControlContext acc;
401 
402         PrivilegedCallable(Callable<T> task) {
403             this.task = task;
404             this.acc = AccessController.getContext();
405         }
406 
407         public T call() throws Exception {
408             try {
409                 return AccessController.doPrivileged(
410                     new PrivilegedExceptionAction<T>() {
411                         public T run() throws Exception {
412                             return task.call();
413                         }
414                     }, acc);
415             } catch (PrivilegedActionException e) {
416                 throw e.getException();
417             }
418         }
419     }
420 
421     /**
422      * A callable that runs under established access control settings and
423      * current ClassLoader
424      */
425     static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> {
426         private final Callable<T> task;
427         private final AccessControlContext acc;
428         private final ClassLoader ccl;
429 
430         PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
431             // BEGIN android-removed
432             // SecurityManager sm = System.getSecurityManager();
433             // if (sm != null) {
434             //     // Calls to getContextClassLoader from this class
435             //     // never trigger a security check, but we check
436             //     // whether our callers have this permission anyways.
437             //     sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
438             //
439             //     // Whether setContextClassLoader turns out to be necessary
440             //     // or not, we fail fast if permission is not available.
441             //     sm.checkPermission(new RuntimePermission("setContextClassLoader"));
442             // }
443             // END android-removed
444             this.task = task;
445             this.acc = AccessController.getContext();
446             this.ccl = Thread.currentThread().getContextClassLoader();
447         }
448 
449         public T call() throws Exception {
450             try {
451                 return AccessController.doPrivileged(
452                     new PrivilegedExceptionAction<T>() {
453                         public T run() throws Exception {
454                             ClassLoader savedcl = null;
455                             Thread t = Thread.currentThread();
456                             try {
457                                 ClassLoader cl = t.getContextClassLoader();
458                                 if (ccl != cl) {
459                                     t.setContextClassLoader(ccl);
460                                     savedcl = cl;
461                                 }
462                                 return task.call();
463                             } finally {
464                                 if (savedcl != null)
465                                     t.setContextClassLoader(savedcl);
466                             }
467                         }
468                     }, acc);
469             } catch (PrivilegedActionException e) {
470                 throw e.getException();
471             }
472         }
473     }
474 
475     /**
476      * The default thread factory
477      */
478     static class DefaultThreadFactory implements ThreadFactory {
479         private static final AtomicInteger poolNumber = new AtomicInteger(1);
480         private final ThreadGroup group;
481         private final AtomicInteger threadNumber = new AtomicInteger(1);
482         private final String namePrefix;
483 
484         DefaultThreadFactory() {
485             SecurityManager s = System.getSecurityManager();
486             group = (s != null) ? s.getThreadGroup() :
487                                   Thread.currentThread().getThreadGroup();
488             namePrefix = "pool-" +
489                           poolNumber.getAndIncrement() +
490                          "-thread-";
491         }
492 
493         public Thread newThread(Runnable r) {
494             Thread t = new Thread(group, r,
495                                   namePrefix + threadNumber.getAndIncrement(),
496                                   0);
497             if (t.isDaemon())
498                 t.setDaemon(false);
499             if (t.getPriority() != Thread.NORM_PRIORITY)
500                 t.setPriority(Thread.NORM_PRIORITY);
501             return t;
502         }
503     }
504 
505     /**
506      * Thread factory capturing access control context and class loader
507      */
508     static class PrivilegedThreadFactory extends DefaultThreadFactory {
509         private final AccessControlContext acc;
510         private final ClassLoader ccl;
511 
512         PrivilegedThreadFactory() {
513             super();
514             // BEGIN android-removed
515             // SecurityManager sm = System.getSecurityManager();
516             // if (sm != null) {
517             //     // Calls to getContextClassLoader from this class
518             //     // never trigger a security check, but we check
519             //     // whether our callers have this permission anyways.
520             //     sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
521             //
522             //     // Fail fast
523             //     sm.checkPermission(new RuntimePermission("setContextClassLoader"));
524             // }
525             // END android-removed
526             this.acc = AccessController.getContext();
527             this.ccl = Thread.currentThread().getContextClassLoader();
528         }
529 
530         public Thread newThread(final Runnable r) {
531             return super.newThread(new Runnable() {
532                 public void run() {
533                     AccessController.doPrivileged(new PrivilegedAction<Void>() {
534                         public Void run() {
535                             Thread.currentThread().setContextClassLoader(ccl);
536                             r.run();
537                             return null;
538                         }
539                     }, acc);
540                 }
541             });
542         }
543     }
544 
545     /**
546      * A wrapper class that exposes only the ExecutorService methods
547      * of an ExecutorService implementation.
548      */
549     static class DelegatedExecutorService extends AbstractExecutorService {
550         private final ExecutorService e;
551         DelegatedExecutorService(ExecutorService executor) { e = executor; }
552         public void execute(Runnable command) { e.execute(command); }
553         public void shutdown() { e.shutdown(); }
554         public List<Runnable> shutdownNow() { return e.shutdownNow(); }
555         public boolean isShutdown() { return e.isShutdown(); }
556         public boolean isTerminated() { return e.isTerminated(); }
557         public boolean awaitTermination(long timeout, TimeUnit unit)
558             throws InterruptedException {
559             return e.awaitTermination(timeout, unit);
560         }
561         public Future<?> submit(Runnable task) {
562             return e.submit(task);
563         }
564         public <T> Future<T> submit(Callable<T> task) {
565             return e.submit(task);
566         }
567         public <T> Future<T> submit(Runnable task, T result) {
568             return e.submit(task, result);
569         }
570         public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
571             throws InterruptedException {
572             return e.invokeAll(tasks);
573         }
574         public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
575                                              long timeout, TimeUnit unit)
576             throws InterruptedException {
577             return e.invokeAll(tasks, timeout, unit);
578         }
579         public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
580             throws InterruptedException, ExecutionException {
581             return e.invokeAny(tasks);
582         }
583         public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
584                                long timeout, TimeUnit unit)
585             throws InterruptedException, ExecutionException, TimeoutException {
586             return e.invokeAny(tasks, timeout, unit);
587         }
588     }
589 
590     static class FinalizableDelegatedExecutorService
591         extends DelegatedExecutorService {
592         FinalizableDelegatedExecutorService(ExecutorService executor) {
593             super(executor);
594         }
595         protected void finalize() {
596             super.shutdown();
597         }
598     }
599 
600     /**
601      * A wrapper class that exposes only the ScheduledExecutorService
602      * methods of a ScheduledExecutorService implementation.
603      */
604     static class DelegatedScheduledExecutorService
605             extends DelegatedExecutorService
606             implements ScheduledExecutorService {
607         private final ScheduledExecutorService e;
608         DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
609             super(executor);
610             e = executor;
611         }
612         public ScheduledFuture<?> schedule(Runnable command, long delay,  TimeUnit unit) {
613             return e.schedule(command, delay, unit);
614         }
615         public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
616             return e.schedule(callable, delay, unit);
617         }
618         public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay,  long period, TimeUnit unit) {
619             return e.scheduleAtFixedRate(command, initialDelay, period, unit);
620         }
621         public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay,  long delay, TimeUnit unit) {
622             return e.scheduleWithFixedDelay(command, initialDelay, delay, unit);
623         }
624     }
625 
626 
627     /** Cannot instantiate. */
628     private Executors() {}
629 }
630