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