ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/Executors.java
Revision: 1.6
Committed: Wed Jun 4 15:28:04 2003 UTC (21 years ago) by tim
Branch: MAIN
Changes since 1.5: +39 -7 lines
Log Message:
Tasks executed on TPEs automatically removed before cancellation attempt.

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain. Use, modify, and
4 * redistribute this code in any way without acknowledgement.
5 */
6
7 package java.util.concurrent;
8 import java.util.*;
9
10 /**
11 * Factory and utility methods for the <tt>Executor</tt> classes
12 * defined in <tt>java.util.concurrent</tt>.
13 *
14 * <p>An Executor is a framework for executing Runnables. The
15 * Executor manages queueing and scheduling of tasks, and creation and
16 * teardown of threads. Depending on which concrete Executor class is
17 * being used, tasks may execute in a newly created thread, an
18 * existing task-execution thread, or the thread calling execute(),
19 * and may execute sequentially or concurrently.
20 *
21 * @since 1.5
22 * @see Executor
23 * @see ExecutorService
24 * @see Future
25 *
26 * @spec JSR-166
27 * @revised $Date: 2003/06/04 11:34:19 $
28 * @editor $Author: dl $
29 */
30 public class Executors {
31
32 /**
33 * A wrapper class that exposes only the ExecutorService methods
34 * of an implementation.
35 */
36 static private class DelegatedExecutorService implements ExecutorService {
37 private final ExecutorService e;
38 DelegatedExecutorService(ExecutorService executor) { e = executor; }
39 public void execute(Runnable command) { e.execute(command); }
40 public void shutdown() { e.shutdown(); }
41 public List shutdownNow() { return e.shutdownNow(); }
42 public boolean isShutdown() { return e.isShutdown(); }
43 public boolean isTerminated() { return e.isTerminated(); }
44 public boolean awaitTermination(long timeout, TimeUnit unit)
45 throws InterruptedException {
46 return e.awaitTermination(timeout, unit);
47 }
48 }
49
50 /**
51 * Creates a thread pool that reuses a fixed set of threads
52 * operating off a shared unbounded queue.
53 *
54 * @param nThreads the number of threads in the pool
55 * @return the newly created thread pool
56 */
57 public static ExecutorService newFixedThreadPool(int nThreads) {
58 return new DelegatedExecutorService
59 (new ThreadPoolExecutor(nThreads, nThreads,
60 0L, TimeUnit.MILLISECONDS,
61 new LinkedBlockingQueue<Runnable>()));
62 }
63
64 /**
65 * Creates a thread pool that reuses a fixed set of threads
66 * operating off a shared unbounded queue, using the provided
67 * ThreadFactory to create new threads when needed.
68 *
69 * @param nThreads the number of threads in the pool
70 * @param threadfactory the factory to use when creating new threads
71 * @return the newly created thread pool
72 */
73 public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
74 return new DelegatedExecutorService
75 (new ThreadPoolExecutor(nThreads, nThreads,
76 0L, TimeUnit.MILLISECONDS,
77 new LinkedBlockingQueue<Runnable>(),
78 threadFactory, null));
79 }
80
81 /**
82 * Creates an Executor that uses a single worker thread operating
83 * off an unbounded queue. (Note however that if this single
84 * thread terminates due to a failure during execution prior to
85 * shutdown, a new one will take its place if needed to execute
86 * subsequent tasks.) Tasks are guaranteed to execute
87 * sequentially, and no more than one task will be active at any
88 * given time.
89 *
90 * @return the newly-created single-threaded Executor
91 */
92 public static ExecutorService newSingleThreadExecutor() {
93 return new DelegatedExecutorService
94 (new ThreadPoolExecutor(1, 1,
95 0L, TimeUnit.MILLISECONDS,
96 new LinkedBlockingQueue<Runnable>()));
97 }
98
99 /**
100 * Creates an Executor that uses a single worker thread operating
101 * off an unbounded queue, and uses the provided ThreadFactory to
102 * create new threads when needed.
103 * @param threadfactory the factory to use when creating new
104 * threads
105 *
106 * @return the newly-created single-threaded Executor
107 */
108 public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
109 return new DelegatedExecutorService
110 (new ThreadPoolExecutor(1, 1,
111 0L, TimeUnit.MILLISECONDS,
112 new LinkedBlockingQueue<Runnable>(),
113 threadFactory, null));
114 }
115
116 /**
117 * Creates a thread pool that creates new threads as needed, but
118 * will reuse previously constructed threads when they are
119 * available. These pools will typically improve the performance
120 * of programs that execute many short-lived asynchronous tasks.
121 * Calls to <tt>execute</tt> will reuse previously constructed
122 * threads if available. If no existing thread is available, a new
123 * thread will be created and added to the pool. Threads that have
124 * not been used for sixty seconds are terminated and removed from
125 * the cache. Thus, a pool that remains idle for long enough will
126 * not consume any resources.
127 *
128 * @return the newly created thread pool
129 */
130 public static ExecutorService newCachedThreadPool() {
131 return new DelegatedExecutorService
132 (new ThreadPoolExecutor(0, Integer.MAX_VALUE,
133 60, TimeUnit.SECONDS,
134 new SynchronousQueue<Runnable>()));
135 }
136
137 /**
138 * Creates a thread pool that creates new threads as needed, but
139 * will reuse previously constructed threads when they are
140 * available, and uses the provided
141 * ThreadFactory to create new threads when needed.
142 * @param threadfactory the factory to use when creating new threads
143 * @return the newly created thread pool
144 */
145 public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
146 return new DelegatedExecutorService
147 (new ThreadPoolExecutor(0, Integer.MAX_VALUE,
148 60, TimeUnit.SECONDS,
149 new SynchronousQueue<Runnable>(),
150 threadFactory, null));
151 }
152
153 /**
154 * Executes a Runnable task and returns a Future representing that
155 * task.
156 *
157 * @param executor the Executor to which the task will be submitted
158 * @param task the task to submit
159 * @param value the value which will become the return value of
160 * the task upon task completion
161 * @return a Future representing pending completion of the task
162 * @throws CannotExecuteException if the task cannot be scheduled
163 * for execution
164 */
165 public static <T> Future<T> execute(Executor executor, Runnable task, T value) {
166 FutureTask<T> ftask;
167 if (executor instanceof ThreadPoolExecutor) {
168 ftask = new ThreadPoolFutureTask<T>(
169 (ThreadPoolExecutor) executor, task, value);
170 } else {
171 ftask = new FutureTask<T>(task, value);
172 }
173 executor.execute(ftask);
174 return ftask;
175 }
176
177 /**
178 * Executes a value-returning task and returns a Future
179 * representing the pending results of the task.
180 *
181 * @param executor the Executor to which the task will be submitted
182 * @param task the task to submit
183 * @return a Future representing pending completion of the task
184 * @throws CannotExecuteException if task cannot be scheduled for execution
185 */
186 public static <T> FutureTask<T> execute(Executor executor, Callable<T> task) {
187 FutureTask<T> ftask;
188 if (executor instanceof ThreadPoolExecutor) {
189 ftask = new ThreadPoolFutureTask<T>(
190 (ThreadPoolExecutor) executor, task);
191 } else {
192 ftask = new FutureTask<T>(task);
193 }
194 executor.execute(ftask);
195 return ftask;
196 }
197
198 /**
199 * Executes a Runnable task and blocks until it completes normally
200 * or throws an exception.
201 *
202 * @param executor the Executor to which the task will be submitted
203 * @param task the task to submit
204 * @throws CannotExecuteException if task cannot be scheduled for execution
205 */
206 public static void invoke(Executor executor, Runnable task)
207 throws ExecutionException, InterruptedException {
208 FutureTask<Boolean> ftask = new FutureTask(task, Boolean.TRUE);
209 executor.execute(ftask);
210 ftask.get();
211 }
212
213 /**
214 * Executes a value-returning task and blocks until it returns a
215 * value or throws an exception.
216 *
217 * @param executor the Executor to which the task will be submitted
218 * @param task the task to submit
219 * @return a Future representing pending completion of the task
220 * @throws CannotExecuteException if task cannot be scheduled for execution
221 */
222 public static <T> T invoke(Executor executor, Callable<T> task)
223 throws ExecutionException, InterruptedException {
224 FutureTask<T> ftask = new FutureTask<T>(task);
225 executor.execute(ftask);
226 return ftask.get();
227 }
228
229 private static class ThreadPoolFutureTask<V> extends FutureTask<V> {
230
231 ThreadPoolFutureTask(ThreadPoolExecutor tpe, Callable<V> callable) {
232 super(callable);
233 this.tpe = tpe;
234 }
235
236 ThreadPoolFutureTask(ThreadPoolExecutor tpe, Runnable runnable, V result) {
237 super(runnable, result);
238 this.tpe = tpe;
239 }
240
241 public boolean cancel(boolean mayInterruptIfRunning) {
242 tpe.remove(this); // ignore success/failure
243 return super.cancel(mayInterruptIfRunning);
244 }
245
246 private final ThreadPoolExecutor tpe;
247 }
248 }