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 java.lang.ref.Cleaner.Cleanable;
 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 jdk.internal.ref.CleanerFactory;
 50 import sun.security.util.SecurityConstants;
 51 
 52 /**
 53  * Factory and utility methods for {@link Executor}, {@link
 54  * ExecutorService}, {@link ScheduledExecutorService}, {@link
 55  * ThreadFactory}, and {@link Callable} classes defined in this
 56  * package. This class supports the following kinds of methods:
 57  *
 58  * <ul>
 59  *   <li>Methods that create and return an {@link ExecutorService}
 60  *       set up with commonly useful configuration settings.
 61  *   <li>Methods that create and return a {@link ScheduledExecutorService}
 62  *       set up with commonly useful configuration settings.
 63  *   <li>Methods that create and return a "wrapped" ExecutorService, that
 64  *       disables reconfiguration by making implementation-specific methods
 65  *       inaccessible.
 66  *   <li>Methods that create and return a {@link ThreadFactory}
 67  *       that sets newly created threads to a known state.
 68  *   <li>Methods that create and return a {@link Callable}
 69  *       out of other closure-like forms, so they can be used
 70  *       in execution methods requiring {@code Callable}.
 71  * </ul>
 72  *
 73  * @since 1.5
 74  * @author Doug Lea
 75  */
 76 public class Executors {
 77 
 78     /**
 79      * Creates a thread pool that reuses a fixed number of threads
 80      * operating off a shared unbounded queue.  At any point, at most
 81      * {@code nThreads} threads will be active processing tasks.
 82      * If additional tasks are submitted when all threads are active,
 83      * they will wait in the queue until a thread is available.
 84      * If any thread terminates due to a failure during execution
 85      * prior to shutdown, a new one will take its place if needed to
 86      * execute subsequent tasks.  The threads in the pool will exist
 87      * until it is explicitly {@link ExecutorService#shutdown shutdown}.
 88      *
 89      * @param nThreads the number of threads in the pool
 90      * @return the newly created thread pool
 91      * @throws IllegalArgumentException if {@code nThreads <= 0}
 92      */
 93     public static ExecutorService newFixedThreadPool(int nThreads) {
 94         return new ThreadPoolExecutor(nThreads, nThreads,
 95                                       0L, TimeUnit.MILLISECONDS,
 96                                       new LinkedBlockingQueue<Runnable>());
 97     }
 98 
 99     /**
100      * Creates a thread pool that maintains enough threads to support
101      * the given parallelism level, and may use multiple queues to
102      * reduce contention. The parallelism level corresponds to the
103      * maximum number of threads actively engaged in, or available to
104      * engage in, task processing. The actual number of threads may
105      * grow and shrink dynamically. A work-stealing pool makes no
106      * guarantees about the order in which submitted tasks are
107      * executed.
108      *
109      * @param parallelism the targeted parallelism level
110      * @return the newly created thread pool
111      * @throws IllegalArgumentException if {@code parallelism <= 0}
112      * @since 1.8
113      */
114     public static ExecutorService newWorkStealingPool(int parallelism) {
115         return new ForkJoinPool
116             (parallelism,
117              ForkJoinPool.defaultForkJoinWorkerThreadFactory,
118              null, true);
119     }
120 
121     /**
122      * Creates a work-stealing thread pool using the number of
123      * {@linkplain Runtime#availableProcessors available processors}
124      * as its target parallelism level.
125      *
126      * @return the newly created thread pool
127      * @see #newWorkStealingPool(int)
128      * @since 1.8
129      */
130     public static ExecutorService newWorkStealingPool() {
131         return new ForkJoinPool
132             (Runtime.getRuntime().availableProcessors(),
133              ForkJoinPool.defaultForkJoinWorkerThreadFactory,
134              null, true);
135     }
136 
137     /**
138      * Creates a thread pool that reuses a fixed number of threads
139      * operating off a shared unbounded queue, using the provided
140      * ThreadFactory to create new threads when needed.  At any point,
141      * at most {@code nThreads} threads will be active processing
142      * tasks.  If additional tasks are submitted when all threads are
143      * active, they will wait in the queue until a thread is
144      * available.  If any thread terminates due to a failure during
145      * execution prior to shutdown, a new one will take its place if
146      * needed to execute subsequent tasks.  The threads in the pool will
147      * exist until it is explicitly {@link ExecutorService#shutdown
148      * shutdown}.
149      *
150      * @param nThreads the number of threads in the pool
151      * @param threadFactory the factory to use when creating new threads
152      * @return the newly created thread pool
153      * @throws NullPointerException if threadFactory is null
154      * @throws IllegalArgumentException if {@code nThreads <= 0}
155      */
156     public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
157         return new ThreadPoolExecutor(nThreads, nThreads,
158                                       0L, TimeUnit.MILLISECONDS,
159                                       new LinkedBlockingQueue<Runnable>(),
160                                       threadFactory);
161     }
162 
163     /**
164      * Creates an Executor that uses a single worker thread operating
165      * off an unbounded queue. (Note however that if this single
166      * thread terminates due to a failure during execution prior to
167      * shutdown, a new one will take its place if needed to execute
168      * subsequent tasks.)  Tasks are guaranteed to execute
169      * sequentially, and no more than one task will be active at any
170      * given time. Unlike the otherwise equivalent
171      * {@code newFixedThreadPool(1)} the returned executor is
172      * guaranteed not to be reconfigurable to use additional threads.
173      *
174      * @return the newly created single-threaded Executor
175      */
176     public static ExecutorService newSingleThreadExecutor() {
177         return newSingleThreadExecutor(defaultThreadFactory());
178     }
179 
180     /**
181      * Creates an Executor that uses a single worker thread operating
182      * off an unbounded queue, and uses the provided ThreadFactory to
183      * create a new thread when needed. Unlike the otherwise
184      * equivalent {@code newFixedThreadPool(1, threadFactory)} the
185      * returned executor is guaranteed not to be reconfigurable to use
186      * additional threads.
187      *
188      * @param threadFactory the factory to use when creating new threads
189      * @return the newly created single-threaded Executor
190      * @throws NullPointerException if threadFactory is null
191      */
192     public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
193         return new AutoShutdownDelegatedExecutorService
194             (new ThreadPoolExecutor(1, 1,
195                                     0L, TimeUnit.MILLISECONDS,
196                                     new LinkedBlockingQueue<Runnable>(),
197                                     threadFactory));
198     }
199 
200     /**
201      * Creates a thread pool that creates new threads as needed, but
202      * will reuse previously constructed threads when they are
203      * available.  These pools will typically improve the performance
204      * of programs that execute many short-lived asynchronous tasks.
205      * Calls to {@code execute} will reuse previously constructed
206      * threads if available. If no existing thread is available, a new
207      * thread will be created and added to the pool. Threads that have
208      * not been used for sixty seconds are terminated and removed from
209      * the cache. Thus, a pool that remains idle for long enough will
210      * not consume any resources. Note that pools with similar
211      * properties but different details (for example, timeout parameters)
212      * may be created using {@link ThreadPoolExecutor} constructors.
213      *
214      * @return the newly created thread pool
215      */
216     public static ExecutorService newCachedThreadPool() {
217         return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
218                                       60L, TimeUnit.SECONDS,
219                                       new SynchronousQueue<Runnable>());
220     }
221 
222     /**
223      * Creates a thread pool that creates new threads as needed, but
224      * will reuse previously constructed threads when they are
225      * available, and uses the provided
226      * ThreadFactory to create new threads when needed.
227      *
228      * @param threadFactory the factory to use when creating new threads
229      * @return the newly created thread pool
230      * @throws NullPointerException if threadFactory is null
231      */
232     public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
233         return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
234                                       60L, TimeUnit.SECONDS,
235                                       new SynchronousQueue<Runnable>(),
236                                       threadFactory);
237     }
238 
239     /**
240      * Creates an Executor that starts a new Thread for each task.
241      * The number of threads created by the Executor is unbounded.
242      *
243      * <p> Invoking {@link Future#cancel(boolean) cancel(true)} on a {@link
244      * Future Future} representing the pending result of a task submitted to
245      * the Executor will {@link Thread#interrupt() interrupt} the thread
246      * executing the task.
247      *
248      * @param threadFactory the factory to use when creating new threads
249      * @return a new executor that creates a new Thread for each task
250      * @throws NullPointerException if threadFactory is null
251      * @since 21
252      */
253     public static ExecutorService newThreadPerTaskExecutor(ThreadFactory threadFactory) {
254         return ThreadPerTaskExecutor.create(threadFactory);
255     }
256 
257     /**
258      * Creates an Executor that starts a new virtual Thread for each task.
259      * The number of threads created by the Executor is unbounded.
260      *
261      * <p> This method is equivalent to invoking
262      * {@link #newThreadPerTaskExecutor(ThreadFactory)} with a thread factory
263      * that creates virtual threads.
264      *
265      * @return a new executor that creates a new virtual Thread for each task
266      * @since 21
267      */
268     public static ExecutorService newVirtualThreadPerTaskExecutor() {
269         ThreadFactory factory = Thread.ofVirtual().factory();
270         return newThreadPerTaskExecutor(factory);
271     }
272 
273     /**
274      * Creates a single-threaded executor that can schedule commands
275      * to run after a given delay, or to execute periodically.
276      * (Note however that if this single
277      * thread terminates due to a failure during execution prior to
278      * shutdown, a new one will take its place if needed to execute
279      * subsequent tasks.)  Tasks are guaranteed to execute
280      * sequentially, and no more than one task will be active at any
281      * given time. Unlike the otherwise equivalent
282      * {@code newScheduledThreadPool(1)} the returned executor is
283      * guaranteed not to be reconfigurable to use additional threads.
284      *
285      * @return the newly created scheduled executor
286      */
287     public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
288         return new DelegatedScheduledExecutorService
289             (new ScheduledThreadPoolExecutor(1));
290     }
291 
292     /**
293      * Creates a single-threaded executor that can schedule commands
294      * to run after a given delay, or to execute periodically.  (Note
295      * however that if this single thread terminates due to a failure
296      * during execution prior to shutdown, a new one will take its
297      * place if needed to execute subsequent tasks.)  Tasks are
298      * guaranteed to execute sequentially, and no more than one task
299      * will be active at any given time. Unlike the otherwise
300      * equivalent {@code newScheduledThreadPool(1, threadFactory)}
301      * the returned executor is guaranteed not to be reconfigurable to
302      * use additional threads.
303      *
304      * @param threadFactory the factory to use when creating new threads
305      * @return the newly created scheduled executor
306      * @throws NullPointerException if threadFactory is null
307      */
308     public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
309         return new DelegatedScheduledExecutorService
310             (new ScheduledThreadPoolExecutor(1, threadFactory));
311     }
312 
313     /**
314      * Creates a thread pool that can schedule commands to run after a
315      * given delay, or to execute periodically.
316      * @param corePoolSize the number of threads to keep in the pool,
317      * even if they are idle
318      * @return the newly created scheduled thread pool
319      * @throws IllegalArgumentException if {@code corePoolSize < 0}
320      */
321     public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
322         return new ScheduledThreadPoolExecutor(corePoolSize);
323     }
324 
325     /**
326      * Creates a thread pool that can schedule commands to run after a
327      * given delay, or to execute periodically.
328      * @param corePoolSize the number of threads to keep in the pool,
329      * even if they are idle
330      * @param threadFactory the factory to use when the executor
331      * creates a new thread
332      * @return the newly created scheduled thread pool
333      * @throws IllegalArgumentException if {@code corePoolSize < 0}
334      * @throws NullPointerException if threadFactory is null
335      */
336     public static ScheduledExecutorService newScheduledThreadPool(
337             int corePoolSize, ThreadFactory threadFactory) {
338         return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
339     }
340 
341     /**
342      * Returns an object that delegates all defined {@link
343      * ExecutorService} methods to the given executor, but not any
344      * other methods that might otherwise be accessible using
345      * casts. This provides a way to safely "freeze" configuration and
346      * disallow tuning of a given concrete implementation.
347      * @param executor the underlying implementation
348      * @return an {@code ExecutorService} instance
349      * @throws NullPointerException if executor null
350      */
351     public static ExecutorService unconfigurableExecutorService(ExecutorService executor) {
352         if (executor == null)
353             throw new NullPointerException();
354         return new DelegatedExecutorService(executor);
355     }
356 
357     /**
358      * Returns an object that delegates all defined {@link
359      * ScheduledExecutorService} methods to the given executor, but
360      * not any other methods that might otherwise be accessible using
361      * casts. This provides a way to safely "freeze" configuration and
362      * disallow tuning of a given concrete implementation.
363      * @param executor the underlying implementation
364      * @return a {@code ScheduledExecutorService} instance
365      * @throws NullPointerException if executor null
366      */
367     public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) {
368         if (executor == null)
369             throw new NullPointerException();
370         return new DelegatedScheduledExecutorService(executor);
371     }
372 
373     /**
374      * Returns a default thread factory used to create new threads.
375      * This factory creates all new threads used by an Executor in the
376      * same {@link ThreadGroup}. If there is a {@link
377      * java.lang.SecurityManager}, it uses the group of {@link
378      * System#getSecurityManager}, else the group of the thread
379      * invoking this {@code defaultThreadFactory} method. Each new
380      * thread is created as a non-daemon thread with priority set to
381      * the smaller of {@code Thread.NORM_PRIORITY} and the maximum
382      * priority permitted in the thread group.  New threads have names
383      * accessible via {@link Thread#getName} of
384      * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence
385      * number of this factory, and <em>M</em> is the sequence number
386      * of the thread created by this factory.
387      * @return a thread factory
388      */
389     public static ThreadFactory defaultThreadFactory() {
390         return new DefaultThreadFactory();
391     }
392 
393     /**
394      * Returns a thread factory used to create new threads that
395      * have the same permissions as the current thread.
396      * This factory creates threads with the same settings as {@link
397      * Executors#defaultThreadFactory}, additionally setting the
398      * AccessControlContext and contextClassLoader of new threads to
399      * be the same as the thread invoking this
400      * {@code privilegedThreadFactory} method.  A new
401      * {@code privilegedThreadFactory} can be created within an
402      * {@link AccessController#doPrivileged AccessController.doPrivileged}
403      * action setting the current thread's access control context to
404      * create threads with the selected permission settings holding
405      * within that action.
406      *
407      * <p>Note that while tasks running within such threads will have
408      * the same access control and class loader settings as the
409      * current thread, they need not have the same {@link
410      * java.lang.ThreadLocal} or {@link
411      * java.lang.InheritableThreadLocal} values. If necessary,
412      * particular values of thread locals can be set or reset before
413      * any task runs in {@link ThreadPoolExecutor} subclasses using
414      * {@link ThreadPoolExecutor#beforeExecute(Thread, Runnable)}.
415      * Also, if it is necessary to initialize worker threads to have
416      * the same InheritableThreadLocal settings as some other
417      * designated thread, you can create a custom ThreadFactory in
418      * which that thread waits for and services requests to create
419      * others that will inherit its values.
420      *
421      * @return a thread factory
422      * @throws AccessControlException if the current access control
423      * context does not have permission to both get and set context
424      * class loader
425      *
426      * @deprecated This method is only useful in conjunction with
427      *       {@linkplain SecurityManager the Security Manager}, which is
428      *       deprecated and subject to removal in a future release.
429      *       Consequently, this method is also deprecated and subject to
430      *       removal. There is no replacement for the Security Manager or this
431      *       method.
432      */
433     @Deprecated(since="17", forRemoval=true)
434     public static ThreadFactory privilegedThreadFactory() {
435         return new PrivilegedThreadFactory();
436     }
437 
438     /**
439      * Returns a {@link Callable} object that, when
440      * called, runs the given task and returns the given result.  This
441      * can be useful when applying methods requiring a
442      * {@code Callable} to an otherwise resultless action.
443      * @param task the task to run
444      * @param result the result to return
445      * @param <T> the type of the result
446      * @return a callable object
447      * @throws NullPointerException if task null
448      */
449     public static <T> Callable<T> callable(Runnable task, T result) {
450         if (task == null)
451             throw new NullPointerException();
452         return new RunnableAdapter<T>(task, result);
453     }
454 
455     /**
456      * Returns a {@link Callable} object that, when
457      * called, runs the given task and returns {@code null}.
458      * @param task the task to run
459      * @return a callable object
460      * @throws NullPointerException if task null
461      */
462     public static Callable<Object> callable(Runnable task) {
463         if (task == null)
464             throw new NullPointerException();
465         return new RunnableAdapter<Object>(task, null);
466     }
467 
468     /**
469      * Returns a {@link Callable} object that, when
470      * called, runs the given privileged action and returns its result.
471      * @param action the privileged action to run
472      * @return a callable object
473      * @throws NullPointerException if action null
474      */
475     public static Callable<Object> callable(final PrivilegedAction<?> action) {
476         if (action == null)
477             throw new NullPointerException();
478         return new Callable<Object>() {
479             public Object call() { return action.run(); }};
480     }
481 
482     /**
483      * Returns a {@link Callable} object that, when
484      * called, runs the given privileged exception action and returns
485      * its result.
486      * @param action the privileged exception action to run
487      * @return a callable object
488      * @throws NullPointerException if action null
489      */
490     public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) {
491         if (action == null)
492             throw new NullPointerException();
493         return new Callable<Object>() {
494             public Object call() throws Exception { return action.run(); }};
495     }
496 
497     /**
498      * Returns a {@link Callable} object that will, when called,
499      * execute the given {@code callable} under the current access
500      * control context. This method should normally be invoked within
501      * an {@link AccessController#doPrivileged AccessController.doPrivileged}
502      * action to create callables that will, if possible, execute
503      * under the selected permission settings holding within that
504      * action; or if not possible, throw an associated {@link
505      * AccessControlException}.
506      * @param callable the underlying task
507      * @param <T> the type of the callable's result
508      * @return a callable object
509      * @throws NullPointerException if callable null
510      *
511      * @deprecated This method is only useful in conjunction with
512      *       {@linkplain SecurityManager the Security Manager}, which is
513      *       deprecated and subject to removal in a future release.
514      *       Consequently, this method is also deprecated and subject to
515      *       removal. There is no replacement for the Security Manager or this
516      *       method.
517      */
518     @Deprecated(since="17", forRemoval=true)
519     public static <T> Callable<T> privilegedCallable(Callable<T> callable) {
520         if (callable == null)
521             throw new NullPointerException();
522         return new PrivilegedCallable<T>(callable);
523     }
524 
525     /**
526      * Returns a {@link Callable} object that will, when called,
527      * execute the given {@code callable} under the current access
528      * control context, with the current context class loader as the
529      * context class loader. This method should normally be invoked
530      * within an
531      * {@link AccessController#doPrivileged AccessController.doPrivileged}
532      * action to create callables that will, if possible, execute
533      * under the selected permission settings holding within that
534      * action; or if not possible, throw an associated {@link
535      * AccessControlException}.
536      *
537      * @param callable the underlying task
538      * @param <T> the type of the callable's result
539      * @return a callable object
540      * @throws NullPointerException if callable null
541      * @throws AccessControlException if the current access control
542      * context does not have permission to both set and get context
543      * class loader
544      *
545      * @deprecated This method is only useful in conjunction with
546      *       {@linkplain SecurityManager the Security Manager}, which is
547      *       deprecated and subject to removal in a future release.
548      *       Consequently, this method is also deprecated and subject to
549      *       removal. There is no replacement for the Security Manager or this
550      *       method.
551      */
552     @Deprecated(since="17", forRemoval=true)
553     public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) {
554         if (callable == null)
555             throw new NullPointerException();
556         return new PrivilegedCallableUsingCurrentClassLoader<T>(callable);
557     }
558 
559     // Non-public classes supporting the public methods
560 
561     /**
562      * A callable that runs given task and returns given result.
563      */
564     private static final class RunnableAdapter<T> implements Callable<T> {
565         private final Runnable task;
566         private final T result;
567         RunnableAdapter(Runnable task, T result) {
568             this.task = task;
569             this.result = result;
570         }
571         public T call() {
572             task.run();
573             return result;
574         }
575         public String toString() {
576             return super.toString() + "[Wrapped task = " + task + "]";
577         }
578     }
579 
580     /**
581      * A callable that runs under established access control settings.
582      */
583     private static final class PrivilegedCallable<T> implements Callable<T> {
584         final Callable<T> task;
585         @SuppressWarnings("removal")
586         final AccessControlContext acc;
587 
588         @SuppressWarnings("removal")
589         PrivilegedCallable(Callable<T> task) {
590             this.task = task;
591             this.acc = AccessController.getContext();
592         }
593 
594         @SuppressWarnings("removal")
595         public T call() throws Exception {
596             try {
597                 return AccessController.doPrivileged(
598                     new PrivilegedExceptionAction<T>() {
599                         public T run() throws Exception {
600                             return task.call();
601                         }
602                     }, acc);
603             } catch (PrivilegedActionException e) {
604                 throw e.getException();
605             }
606         }
607 
608         public String toString() {
609             return super.toString() + "[Wrapped task = " + task + "]";
610         }
611     }
612 
613     /**
614      * A callable that runs under established access control settings and
615      * current ClassLoader.
616      */
617     private static final class PrivilegedCallableUsingCurrentClassLoader<T>
618             implements Callable<T> {
619         final Callable<T> task;
620         @SuppressWarnings("removal")
621         final AccessControlContext acc;
622         final ClassLoader ccl;
623 
624         @SuppressWarnings("removal")
625         PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
626             SecurityManager sm = System.getSecurityManager();
627             if (sm != null) {
628                 // Calls to getContextClassLoader from this class
629                 // never trigger a security check, but we check
630                 // whether our callers have this permission anyways.
631                 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
632 
633                 // Whether setContextClassLoader turns out to be necessary
634                 // or not, we fail fast if permission is not available.
635                 sm.checkPermission(new RuntimePermission("setContextClassLoader"));
636             }
637             this.task = task;
638             this.acc = AccessController.getContext();
639             this.ccl = Thread.currentThread().getContextClassLoader();
640         }
641 
642         @SuppressWarnings("removal")
643         public T call() throws Exception {
644             try {
645                 return AccessController.doPrivileged(
646                     new PrivilegedExceptionAction<T>() {
647                         public T run() throws Exception {
648                             Thread t = Thread.currentThread();
649                             ClassLoader cl = t.getContextClassLoader();
650                             if (ccl == cl) {
651                                 return task.call();
652                             } else {
653                                 t.setContextClassLoader(ccl);
654                                 try {
655                                     return task.call();
656                                 } finally {
657                                     t.setContextClassLoader(cl);
658                                 }
659                             }
660                         }
661                     }, acc);
662             } catch (PrivilegedActionException e) {
663                 throw e.getException();
664             }
665         }
666 
667         public String toString() {
668             return super.toString() + "[Wrapped task = " + task + "]";
669         }
670     }
671 
672     /**
673      * The default thread factory.
674      */
675     private static class DefaultThreadFactory implements ThreadFactory {
676         private static final AtomicInteger poolNumber = new AtomicInteger(1);
677         private final ThreadGroup group;
678         private final AtomicInteger threadNumber = new AtomicInteger(1);
679         private final String namePrefix;
680 
681         DefaultThreadFactory() {
682             @SuppressWarnings("removal")
683             SecurityManager s = System.getSecurityManager();
684             group = (s != null) ? s.getThreadGroup() :
685                                   Thread.currentThread().getThreadGroup();
686             namePrefix = "pool-" +
687                           poolNumber.getAndIncrement() +
688                          "-thread-";
689         }
690 
691         public Thread newThread(Runnable r) {
692             Thread t = new Thread(group, r,
693                                   namePrefix + threadNumber.getAndIncrement(),
694                                   0);
695             if (t.isDaemon())
696                 t.setDaemon(false);
697             if (t.getPriority() != Thread.NORM_PRIORITY)
698                 t.setPriority(Thread.NORM_PRIORITY);
699             return t;
700         }
701     }
702 
703     /**
704      * Thread factory capturing access control context and class loader.
705      */
706     private static class PrivilegedThreadFactory extends DefaultThreadFactory {
707         @SuppressWarnings("removal")
708         final AccessControlContext acc;
709         final ClassLoader ccl;
710 
711         @SuppressWarnings("removal")
712         PrivilegedThreadFactory() {
713             super();
714             SecurityManager sm = System.getSecurityManager();
715             if (sm != null) {
716                 // Calls to getContextClassLoader from this class
717                 // never trigger a security check, but we check
718                 // whether our callers have this permission anyways.
719                 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
720 
721                 // Fail fast
722                 sm.checkPermission(new RuntimePermission("setContextClassLoader"));
723             }
724             this.acc = AccessController.getContext();
725             this.ccl = Thread.currentThread().getContextClassLoader();
726         }
727 
728         public Thread newThread(final Runnable r) {
729             return super.newThread(new Runnable() {
730                 @SuppressWarnings("removal")
731                 public void run() {
732                     AccessController.doPrivileged(new PrivilegedAction<>() {
733                         public Void run() {
734                             Thread.currentThread().setContextClassLoader(ccl);
735                             r.run();
736                             return null;
737                         }
738                     }, acc);
739                 }
740             });
741         }
742     }
743 
744     /**
745      * A wrapper class that exposes only the ExecutorService methods
746      * of an ExecutorService implementation.
747      */
748     private static class DelegatedExecutorService
749             implements ExecutorService {
750         private final ExecutorService e;
751         DelegatedExecutorService(ExecutorService executor) { e = executor; }
752         public void execute(Runnable command) {
753             try {
754                 e.execute(command);
755             } finally { reachabilityFence(this); }
756         }
757         public void shutdown() {
758             try {
759                 e.shutdown();
760             } finally { reachabilityFence(this); }
761         }
762         public List<Runnable> shutdownNow() {
763             try {
764                 return e.shutdownNow();
765             } finally { reachabilityFence(this); }
766         }
767         public boolean isShutdown() {
768             try {
769                 return e.isShutdown();
770             } finally { reachabilityFence(this); }
771         }
772         public boolean isTerminated() {
773             try {
774                 return e.isTerminated();
775             } finally { reachabilityFence(this); }
776         }
777         public boolean awaitTermination(long timeout, TimeUnit unit)
778             throws InterruptedException {
779             try {
780                 return e.awaitTermination(timeout, unit);
781             } finally { reachabilityFence(this); }
782         }
783         public Future<?> submit(Runnable task) {
784             try {
785                 return e.submit(task);
786             } finally { reachabilityFence(this); }
787         }
788         public <T> Future<T> submit(Callable<T> task) {
789             try {
790                 return e.submit(task);
791             } finally { reachabilityFence(this); }
792         }
793         public <T> Future<T> submit(Runnable task, T result) {
794             try {
795                 return e.submit(task, result);
796             } finally { reachabilityFence(this); }
797         }
798         public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
799             throws InterruptedException {
800             try {
801                 return e.invokeAll(tasks);
802             } finally { reachabilityFence(this); }
803         }
804         public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
805                                              long timeout, TimeUnit unit)
806             throws InterruptedException {
807             try {
808                 return e.invokeAll(tasks, timeout, unit);
809             } finally { reachabilityFence(this); }
810         }
811         public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
812             throws InterruptedException, ExecutionException {
813             try {
814                 return e.invokeAny(tasks);
815             } finally { reachabilityFence(this); }
816         }
817         public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
818                                long timeout, TimeUnit unit)
819             throws InterruptedException, ExecutionException, TimeoutException {
820             try {
821                 return e.invokeAny(tasks, timeout, unit);
822             } finally { reachabilityFence(this); }
823         }
824     }
825 
826     /**
827      * A DelegatedExecutorService that uses a Cleaner to shut down the underlying
828      * ExecutorService when the wrapper becomes phantom reachable.
829      */
830     private static class AutoShutdownDelegatedExecutorService
831             extends DelegatedExecutorService {
832         private final Cleanable cleanable;
833         AutoShutdownDelegatedExecutorService(ExecutorService executor) {
834             super(executor);
835             Runnable action = () -> {
836                 if (!executor.isShutdown()) {
837                     PrivilegedAction<Void> pa = () -> { executor.shutdown(); return null; };
838                     @SuppressWarnings("removal")
839                     var ignore = AccessController.doPrivileged(pa);
840                 }
841             };
842             cleanable = CleanerFactory.cleaner().register(this, action);
843         }
844         @Override
845         public void shutdown() {
846             super.shutdown();
847             cleanable.clean();  // unregisters the cleanable
848         }
849     }
850 
851     /**
852      * A wrapper class that exposes only the ScheduledExecutorService
853      * methods of a ScheduledExecutorService implementation.
854      */
855     private static class DelegatedScheduledExecutorService
856             extends DelegatedExecutorService
857             implements ScheduledExecutorService {
858         private final ScheduledExecutorService e;
859         DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
860             super(executor);
861             e = executor;
862         }
863         public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
864             return e.schedule(command, delay, unit);
865         }
866         public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
867             return e.schedule(callable, delay, unit);
868         }
869         public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
870             return e.scheduleAtFixedRate(command, initialDelay, period, unit);
871         }
872         public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
873             return e.scheduleWithFixedDelay(command, initialDelay, delay, unit);
874         }
875     }
876 
877     /** Cannot instantiate. */
878     private Executors() {}
879 }