jdk/src/share/classes/java/util/concurrent/Executors.java
changeset 2 90ce3da70b43
child 5506 202f599c92aa
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     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.  Sun designates this
       
     7  * particular file as subject to the "Classpath" exception as provided
       
     8  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    21  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    22  * have any 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/licenses/publicdomain
       
    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 <tt>nThreads &lt;= 0</tt>
       
    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 <tt>nThreads &lt;= 0</tt>
       
   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 <tt>corePoolSize &lt; 0</tt>
       
   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 <tt>corePoolSize &lt; 0</tt>
       
   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 }