ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/Executors.java
Revision: 1.47
Committed: Sun Jan 11 23:19:55 2004 UTC (20 years, 4 months ago) by dl
Branch: MAIN
Changes since 1.46: +2 -3 lines
Log Message:
formatting; grammar

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