ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk7/java/util/concurrent/Executors.java
Revision: 1.7
Committed: Sun Sep 13 16:28:13 2015 UTC (8 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.6: +12 -12 lines
Log Message:
consistent style for <li> tags, removing </li> end tags

File Contents

# User Rev Content
1 dl 1.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 jsr166 1.6
9 dl 1.1 import java.util.*;
10     import java.util.concurrent.atomic.AtomicInteger;
11     import java.security.AccessControlContext;
12     import java.security.AccessController;
13     import java.security.PrivilegedAction;
14     import java.security.PrivilegedExceptionAction;
15     import java.security.PrivilegedActionException;
16     import java.security.AccessControlException;
17     import sun.security.util.SecurityConstants;
18    
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 jsr166 1.7 * <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 {@code Callable}.
38 dl 1.1 * </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 jsr166 1.2 * {@code nThreads} threads will be active processing tasks.
49 dl 1.1 * 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     */
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 maintains enough threads to support
68     * the given parallelism level, and may use multiple queues to
69     * reduce contention. The parallelism level corresponds to the
70     * maximum number of threads actively engaged in, or available to
71     * engage in, task processing. The actual number of threads may
72     * grow and shrink dynamically. A work-stealing pool makes no
73     * guarantees about the order in which submitted tasks are
74     * executed.
75     *
76     * @param parallelism the targeted parallelism level
77     * @return the newly created thread pool
78     * @throws IllegalArgumentException if {@code parallelism <= 0}
79     * @since 1.8
80     */
81     public static ExecutorService newWorkStealingPool(int parallelism) {
82     return new ForkJoinPool
83     (parallelism,
84     ForkJoinPool.defaultForkJoinWorkerThreadFactory,
85     null, true);
86     }
87    
88     /**
89     * Creates a work-stealing thread pool using all
90 jsr166 1.4 * {@link Runtime#availableProcessors available processors}
91 dl 1.1 * as its target parallelism level.
92     * @return the newly created thread pool
93     * @since 1.8
94     */
95     public static ExecutorService newWorkStealingPool() {
96     return new ForkJoinPool
97     (Runtime.getRuntime().availableProcessors(),
98     ForkJoinPool.defaultForkJoinWorkerThreadFactory,
99     null, true);
100     }
101    
102     /**
103     * Creates a thread pool that reuses a fixed number of threads
104     * operating off a shared unbounded queue, using the provided
105     * ThreadFactory to create new threads when needed. At any point,
106 jsr166 1.2 * at most {@code nThreads} threads will be active processing
107 dl 1.1 * tasks. If additional tasks are submitted when all threads are
108     * active, they will wait in the queue until a thread is
109     * available. If any thread terminates due to a failure during
110     * execution prior to shutdown, a new one will take its place if
111     * needed to execute subsequent tasks. The threads in the pool will
112     * exist until it is explicitly {@link ExecutorService#shutdown
113     * shutdown}.
114     *
115     * @param nThreads the number of threads in the pool
116     * @param threadFactory the factory to use when creating new threads
117     * @return the newly created thread pool
118     * @throws NullPointerException if threadFactory is null
119     * @throws IllegalArgumentException if {@code nThreads <= 0}
120     */
121     public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
122     return new ThreadPoolExecutor(nThreads, nThreads,
123     0L, TimeUnit.MILLISECONDS,
124     new LinkedBlockingQueue<Runnable>(),
125     threadFactory);
126     }
127    
128     /**
129     * Creates an Executor that uses a single worker thread operating
130     * off an unbounded queue. (Note however that if this single
131     * thread terminates due to a failure during execution prior to
132     * shutdown, a new one will take its place if needed to execute
133     * subsequent tasks.) Tasks are guaranteed to execute
134     * sequentially, and no more than one task will be active at any
135     * given time. Unlike the otherwise equivalent
136 jsr166 1.2 * {@code newFixedThreadPool(1)} the returned executor is
137 dl 1.1 * guaranteed not to be reconfigurable to use additional threads.
138     *
139     * @return the newly created single-threaded Executor
140     */
141     public static ExecutorService newSingleThreadExecutor() {
142     return new FinalizableDelegatedExecutorService
143     (new ThreadPoolExecutor(1, 1,
144     0L, TimeUnit.MILLISECONDS,
145     new LinkedBlockingQueue<Runnable>()));
146     }
147    
148     /**
149     * Creates an Executor that uses a single worker thread operating
150     * off an unbounded queue, and uses the provided ThreadFactory to
151     * create a new thread when needed. Unlike the otherwise
152 jsr166 1.2 * equivalent {@code newFixedThreadPool(1, threadFactory)} the
153 dl 1.1 * returned executor is guaranteed not to be reconfigurable to use
154     * additional threads.
155     *
156     * @param threadFactory the factory to use when creating new
157     * threads
158     *
159     * @return the newly created single-threaded Executor
160     * @throws NullPointerException if threadFactory is null
161     */
162     public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
163     return new FinalizableDelegatedExecutorService
164     (new ThreadPoolExecutor(1, 1,
165     0L, TimeUnit.MILLISECONDS,
166     new LinkedBlockingQueue<Runnable>(),
167     threadFactory));
168     }
169    
170     /**
171     * Creates a thread pool that creates new threads as needed, but
172     * will reuse previously constructed threads when they are
173     * available. These pools will typically improve the performance
174     * of programs that execute many short-lived asynchronous tasks.
175 jsr166 1.2 * Calls to {@code execute} will reuse previously constructed
176 dl 1.1 * threads if available. If no existing thread is available, a new
177     * thread will be created and added to the pool. Threads that have
178     * not been used for sixty seconds are terminated and removed from
179     * the cache. Thus, a pool that remains idle for long enough will
180     * not consume any resources. Note that pools with similar
181     * properties but different details (for example, timeout parameters)
182     * may be created using {@link ThreadPoolExecutor} constructors.
183     *
184     * @return the newly created thread pool
185     */
186     public static ExecutorService newCachedThreadPool() {
187     return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
188     60L, TimeUnit.SECONDS,
189     new SynchronousQueue<Runnable>());
190     }
191    
192     /**
193     * Creates a thread pool that creates new threads as needed, but
194     * will reuse previously constructed threads when they are
195     * available, and uses the provided
196     * ThreadFactory to create new threads when needed.
197     * @param threadFactory the factory to use when creating new threads
198     * @return the newly created thread pool
199     * @throws NullPointerException if threadFactory is null
200     */
201     public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
202     return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
203     60L, TimeUnit.SECONDS,
204     new SynchronousQueue<Runnable>(),
205     threadFactory);
206     }
207    
208     /**
209     * Creates a single-threaded executor that can schedule commands
210     * to run after a given delay, or to execute periodically.
211     * (Note however that if this single
212     * thread terminates due to a failure during execution prior to
213     * shutdown, a new one will take its place if needed to execute
214     * subsequent tasks.) Tasks are guaranteed to execute
215     * sequentially, and no more than one task will be active at any
216     * given time. Unlike the otherwise equivalent
217 jsr166 1.2 * {@code newScheduledThreadPool(1)} the returned executor is
218 dl 1.1 * guaranteed not to be reconfigurable to use additional threads.
219     * @return the newly created scheduled executor
220     */
221     public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
222     return new DelegatedScheduledExecutorService
223     (new ScheduledThreadPoolExecutor(1));
224     }
225    
226     /**
227     * Creates a single-threaded executor that can schedule commands
228     * to run after a given delay, or to execute periodically. (Note
229     * however that if this single thread terminates due to a failure
230     * during execution prior to shutdown, a new one will take its
231     * place if needed to execute subsequent tasks.) Tasks are
232     * guaranteed to execute sequentially, and no more than one task
233     * will be active at any given time. Unlike the otherwise
234 jsr166 1.2 * equivalent {@code newScheduledThreadPool(1, threadFactory)}
235 dl 1.1 * the returned executor is guaranteed not to be reconfigurable to
236     * use additional threads.
237     * @param threadFactory the factory to use when creating new
238     * threads
239     * @return a newly created scheduled executor
240     * @throws NullPointerException if threadFactory is null
241     */
242     public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
243     return new DelegatedScheduledExecutorService
244     (new ScheduledThreadPoolExecutor(1, threadFactory));
245     }
246    
247     /**
248     * Creates a thread pool that can schedule commands to run after a
249     * given delay, or to execute periodically.
250     * @param corePoolSize the number of threads to keep in the pool,
251 jsr166 1.3 * even if they are idle
252 dl 1.1 * @return a newly created scheduled thread pool
253     * @throws IllegalArgumentException if {@code corePoolSize < 0}
254     */
255     public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
256     return new ScheduledThreadPoolExecutor(corePoolSize);
257     }
258    
259     /**
260     * Creates a thread pool that can schedule commands to run after a
261     * given delay, or to execute periodically.
262     * @param corePoolSize the number of threads to keep in the pool,
263 jsr166 1.3 * even if they are idle
264 dl 1.1 * @param threadFactory the factory to use when the executor
265 jsr166 1.3 * creates a new thread
266 dl 1.1 * @return a newly created scheduled thread pool
267     * @throws IllegalArgumentException if {@code corePoolSize < 0}
268     * @throws NullPointerException if threadFactory is null
269     */
270     public static ScheduledExecutorService newScheduledThreadPool(
271     int corePoolSize, ThreadFactory threadFactory) {
272     return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
273     }
274    
275     /**
276     * Returns an object that delegates all defined {@link
277     * ExecutorService} methods to the given executor, but not any
278     * other methods that might otherwise be accessible using
279     * casts. This provides a way to safely "freeze" configuration and
280     * disallow tuning of a given concrete implementation.
281     * @param executor the underlying implementation
282 jsr166 1.2 * @return an {@code ExecutorService} instance
283 dl 1.1 * @throws NullPointerException if executor null
284     */
285     public static ExecutorService unconfigurableExecutorService(ExecutorService executor) {
286     if (executor == null)
287     throw new NullPointerException();
288     return new DelegatedExecutorService(executor);
289     }
290    
291     /**
292     * Returns an object that delegates all defined {@link
293     * ScheduledExecutorService} methods to the given executor, but
294     * not any other methods that might otherwise be accessible using
295     * casts. This provides a way to safely "freeze" configuration and
296     * disallow tuning of a given concrete implementation.
297     * @param executor the underlying implementation
298 jsr166 1.2 * @return a {@code ScheduledExecutorService} instance
299 dl 1.1 * @throws NullPointerException if executor null
300     */
301     public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) {
302     if (executor == null)
303     throw new NullPointerException();
304     return new DelegatedScheduledExecutorService(executor);
305     }
306    
307     /**
308     * Returns a default thread factory used to create new threads.
309     * This factory creates all new threads used by an Executor in the
310     * same {@link ThreadGroup}. If there is a {@link
311     * java.lang.SecurityManager}, it uses the group of {@link
312     * System#getSecurityManager}, else the group of the thread
313 jsr166 1.2 * invoking this {@code defaultThreadFactory} method. Each new
314 dl 1.1 * thread is created as a non-daemon thread with priority set to
315 jsr166 1.2 * the smaller of {@code Thread.NORM_PRIORITY} and the maximum
316 dl 1.1 * priority permitted in the thread group. New threads have names
317     * accessible via {@link Thread#getName} of
318     * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence
319     * number of this factory, and <em>M</em> is the sequence number
320     * of the thread created by this factory.
321     * @return a thread factory
322     */
323     public static ThreadFactory defaultThreadFactory() {
324     return new DefaultThreadFactory();
325     }
326    
327     /**
328     * Returns a thread factory used to create new threads that
329     * have the same permissions as the current thread.
330     * This factory creates threads with the same settings as {@link
331     * Executors#defaultThreadFactory}, additionally setting the
332     * AccessControlContext and contextClassLoader of new threads to
333     * be the same as the thread invoking this
334 jsr166 1.2 * {@code privilegedThreadFactory} method. A new
335     * {@code privilegedThreadFactory} can be created within an
336 dl 1.1 * {@link AccessController#doPrivileged} action setting the
337     * current thread's access control context to create threads with
338     * the selected permission settings holding within that action.
339     *
340     * <p>Note that while tasks running within such threads will have
341     * the same access control and class loader settings as the
342     * current thread, they need not have the same {@link
343     * java.lang.ThreadLocal} or {@link
344     * java.lang.InheritableThreadLocal} values. If necessary,
345     * particular values of thread locals can be set or reset before
346     * any task runs in {@link ThreadPoolExecutor} subclasses using
347     * {@link ThreadPoolExecutor#beforeExecute}. Also, if it is
348     * necessary to initialize worker threads to have the same
349     * InheritableThreadLocal settings as some other designated
350     * thread, you can create a custom ThreadFactory in which that
351     * thread waits for and services requests to create others that
352     * will inherit its values.
353     *
354     * @return a thread factory
355     * @throws AccessControlException if the current access control
356     * context does not have permission to both get and set context
357 jsr166 1.3 * class loader
358 dl 1.1 */
359     public static ThreadFactory privilegedThreadFactory() {
360     return new PrivilegedThreadFactory();
361     }
362    
363     /**
364     * Returns a {@link Callable} object that, when
365     * called, runs the given task and returns the given result. This
366     * can be useful when applying methods requiring a
367 jsr166 1.2 * {@code Callable} to an otherwise resultless action.
368 dl 1.1 * @param task the task to run
369     * @param result the result to return
370 jsr166 1.5 * @param <T> the type of the result
371 dl 1.1 * @return a callable object
372     * @throws NullPointerException if task null
373     */
374     public static <T> Callable<T> callable(Runnable task, T result) {
375     if (task == null)
376     throw new NullPointerException();
377     return new RunnableAdapter<T>(task, result);
378     }
379    
380     /**
381     * Returns a {@link Callable} object that, when
382 jsr166 1.2 * called, runs the given task and returns {@code null}.
383 dl 1.1 * @param task the task to run
384     * @return a callable object
385     * @throws NullPointerException if task null
386     */
387     public static Callable<Object> callable(Runnable task) {
388     if (task == null)
389     throw new NullPointerException();
390     return new RunnableAdapter<Object>(task, null);
391     }
392    
393     /**
394     * Returns a {@link Callable} object that, when
395     * called, runs the given privileged action and returns its result.
396     * @param action the privileged action to run
397     * @return a callable object
398     * @throws NullPointerException if action null
399     */
400     public static Callable<Object> callable(final PrivilegedAction<?> action) {
401     if (action == null)
402     throw new NullPointerException();
403     return new Callable<Object>() {
404     public Object call() { return action.run(); }};
405     }
406    
407     /**
408     * Returns a {@link Callable} object that, when
409     * called, runs the given privileged exception action and returns
410     * its result.
411     * @param action the privileged exception action to run
412     * @return a callable object
413     * @throws NullPointerException if action null
414     */
415     public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) {
416     if (action == null)
417     throw new NullPointerException();
418     return new Callable<Object>() {
419     public Object call() throws Exception { return action.run(); }};
420     }
421    
422     /**
423     * Returns a {@link Callable} object that will, when
424 jsr166 1.2 * called, execute the given {@code callable} under the current
425 dl 1.1 * access control context. This method should normally be
426     * invoked within an {@link AccessController#doPrivileged} action
427     * to create callables that will, if possible, execute under the
428     * selected permission settings holding within that action; or if
429     * not possible, throw an associated {@link
430     * AccessControlException}.
431     * @param callable the underlying task
432 jsr166 1.5 * @param <T> the type of the callable's result
433 dl 1.1 * @return a callable object
434     * @throws NullPointerException if callable null
435     */
436     public static <T> Callable<T> privilegedCallable(Callable<T> callable) {
437     if (callable == null)
438     throw new NullPointerException();
439     return new PrivilegedCallable<T>(callable);
440     }
441    
442     /**
443     * Returns a {@link Callable} object that will, when
444 jsr166 1.2 * called, execute the given {@code callable} under the current
445 dl 1.1 * access control context, with the current context class loader
446     * as the context class loader. This method should normally be
447     * invoked within an {@link AccessController#doPrivileged} action
448     * to create callables that will, if possible, execute under the
449     * selected permission settings holding within that action; or if
450     * not possible, throw an associated {@link
451     * AccessControlException}.
452 jsr166 1.3 *
453 dl 1.1 * @param callable the underlying task
454 jsr166 1.5 * @param <T> the type of the callable's result
455 dl 1.1 * @return a callable object
456     * @throws NullPointerException if callable null
457     * @throws AccessControlException if the current access control
458     * context does not have permission to both set and get context
459 jsr166 1.3 * class loader
460 dl 1.1 */
461     public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) {
462     if (callable == null)
463     throw new NullPointerException();
464     return new PrivilegedCallableUsingCurrentClassLoader<T>(callable);
465     }
466    
467     // Non-public classes supporting the public methods
468    
469     /**
470     * A callable that runs given task and returns given result
471     */
472     static final class RunnableAdapter<T> implements Callable<T> {
473     final Runnable task;
474     final T result;
475     RunnableAdapter(Runnable task, T result) {
476     this.task = task;
477     this.result = result;
478     }
479     public T call() {
480     task.run();
481     return result;
482     }
483     }
484    
485     /**
486     * A callable that runs under established access control settings
487     */
488     static final class PrivilegedCallable<T> implements Callable<T> {
489     private final Callable<T> task;
490     private final AccessControlContext acc;
491    
492     PrivilegedCallable(Callable<T> task) {
493     this.task = task;
494     this.acc = AccessController.getContext();
495     }
496    
497     public T call() throws Exception {
498     try {
499     return AccessController.doPrivileged(
500     new PrivilegedExceptionAction<T>() {
501     public T run() throws Exception {
502     return task.call();
503     }
504     }, acc);
505     } catch (PrivilegedActionException e) {
506     throw e.getException();
507     }
508     }
509     }
510    
511     /**
512     * A callable that runs under established access control settings and
513     * current ClassLoader
514     */
515     static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> {
516     private final Callable<T> task;
517     private final AccessControlContext acc;
518     private final ClassLoader ccl;
519    
520     PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
521     SecurityManager sm = System.getSecurityManager();
522     if (sm != null) {
523     // Calls to getContextClassLoader from this class
524     // never trigger a security check, but we check
525     // whether our callers have this permission anyways.
526     sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
527    
528     // Whether setContextClassLoader turns out to be necessary
529     // or not, we fail fast if permission is not available.
530     sm.checkPermission(new RuntimePermission("setContextClassLoader"));
531     }
532     this.task = task;
533     this.acc = AccessController.getContext();
534     this.ccl = Thread.currentThread().getContextClassLoader();
535     }
536    
537     public T call() throws Exception {
538     try {
539     return AccessController.doPrivileged(
540     new PrivilegedExceptionAction<T>() {
541     public T run() throws Exception {
542     Thread t = Thread.currentThread();
543     ClassLoader cl = t.getContextClassLoader();
544     if (ccl == cl) {
545     return task.call();
546     } else {
547     t.setContextClassLoader(ccl);
548     try {
549     return task.call();
550     } finally {
551     t.setContextClassLoader(cl);
552     }
553     }
554     }
555     }, acc);
556     } catch (PrivilegedActionException e) {
557     throw e.getException();
558     }
559     }
560     }
561    
562     /**
563     * The default thread factory
564     */
565     static class DefaultThreadFactory implements ThreadFactory {
566     private static final AtomicInteger poolNumber = new AtomicInteger(1);
567     private final ThreadGroup group;
568     private final AtomicInteger threadNumber = new AtomicInteger(1);
569     private final String namePrefix;
570    
571     DefaultThreadFactory() {
572     SecurityManager s = System.getSecurityManager();
573     group = (s != null) ? s.getThreadGroup() :
574     Thread.currentThread().getThreadGroup();
575     namePrefix = "pool-" +
576     poolNumber.getAndIncrement() +
577     "-thread-";
578     }
579    
580     public Thread newThread(Runnable r) {
581     Thread t = new Thread(group, r,
582     namePrefix + threadNumber.getAndIncrement(),
583     0);
584     if (t.isDaemon())
585     t.setDaemon(false);
586     if (t.getPriority() != Thread.NORM_PRIORITY)
587     t.setPriority(Thread.NORM_PRIORITY);
588     return t;
589     }
590     }
591    
592     /**
593     * Thread factory capturing access control context and class loader
594     */
595     static class PrivilegedThreadFactory extends DefaultThreadFactory {
596     private final AccessControlContext acc;
597     private final ClassLoader ccl;
598    
599     PrivilegedThreadFactory() {
600     super();
601     SecurityManager sm = System.getSecurityManager();
602     if (sm != null) {
603     // Calls to getContextClassLoader from this class
604     // never trigger a security check, but we check
605     // whether our callers have this permission anyways.
606     sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
607    
608     // Fail fast
609     sm.checkPermission(new RuntimePermission("setContextClassLoader"));
610     }
611     this.acc = AccessController.getContext();
612     this.ccl = Thread.currentThread().getContextClassLoader();
613     }
614    
615     public Thread newThread(final Runnable r) {
616     return super.newThread(new Runnable() {
617     public void run() {
618     AccessController.doPrivileged(new PrivilegedAction<Void>() {
619     public Void run() {
620     Thread.currentThread().setContextClassLoader(ccl);
621     r.run();
622     return null;
623     }
624     }, acc);
625     }
626     });
627     }
628     }
629    
630     /**
631     * A wrapper class that exposes only the ExecutorService methods
632     * of an ExecutorService implementation.
633     */
634     static class DelegatedExecutorService extends AbstractExecutorService {
635     private final ExecutorService e;
636     DelegatedExecutorService(ExecutorService executor) { e = executor; }
637     public void execute(Runnable command) { e.execute(command); }
638     public void shutdown() { e.shutdown(); }
639     public List<Runnable> shutdownNow() { return e.shutdownNow(); }
640     public boolean isShutdown() { return e.isShutdown(); }
641     public boolean isTerminated() { return e.isTerminated(); }
642     public boolean awaitTermination(long timeout, TimeUnit unit)
643     throws InterruptedException {
644     return e.awaitTermination(timeout, unit);
645     }
646     public Future<?> submit(Runnable task) {
647     return e.submit(task);
648     }
649     public <T> Future<T> submit(Callable<T> task) {
650     return e.submit(task);
651     }
652     public <T> Future<T> submit(Runnable task, T result) {
653     return e.submit(task, result);
654     }
655     public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
656     throws InterruptedException {
657     return e.invokeAll(tasks);
658     }
659     public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
660     long timeout, TimeUnit unit)
661     throws InterruptedException {
662     return e.invokeAll(tasks, timeout, unit);
663     }
664     public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
665     throws InterruptedException, ExecutionException {
666     return e.invokeAny(tasks);
667     }
668     public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
669     long timeout, TimeUnit unit)
670     throws InterruptedException, ExecutionException, TimeoutException {
671     return e.invokeAny(tasks, timeout, unit);
672     }
673     }
674    
675     static class FinalizableDelegatedExecutorService
676     extends DelegatedExecutorService {
677     FinalizableDelegatedExecutorService(ExecutorService executor) {
678     super(executor);
679     }
680     protected void finalize() {
681     super.shutdown();
682     }
683     }
684    
685     /**
686     * A wrapper class that exposes only the ScheduledExecutorService
687     * methods of a ScheduledExecutorService implementation.
688     */
689     static class DelegatedScheduledExecutorService
690     extends DelegatedExecutorService
691     implements ScheduledExecutorService {
692     private final ScheduledExecutorService e;
693     DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
694     super(executor);
695     e = executor;
696     }
697     public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
698     return e.schedule(command, delay, unit);
699     }
700     public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
701     return e.schedule(callable, delay, unit);
702     }
703     public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
704     return e.scheduleAtFixedRate(command, initialDelay, period, unit);
705     }
706     public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
707     return e.scheduleWithFixedDelay(command, initialDelay, delay, unit);
708     }
709     }
710    
711     /** Cannot instantiate. */
712     private Executors() {}
713     }