ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk7/java/util/concurrent/Executors.java
Revision: 1.8
Committed: Tue Oct 13 20:20:05 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.7: +3 -2 lines
Log Message:
small @link readability improvements

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