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