ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/Executors.java
Revision: 1.64
Committed: Tue Mar 21 00:22:43 2006 UTC (18 years, 2 months ago) by dl
Branch: MAIN
Changes since 1.63: +4 -0 lines
Log Message:
Document and better support finalization

File Contents

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