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