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