ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ExecutorService.java
Revision: 1.67
Committed: Fri Nov 25 16:39:48 2022 UTC (17 months, 3 weeks ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.66: +2 -2 lines
Log Message:
whitespace

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, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 package java.util.concurrent;
8
9 import java.util.Collection;
10 import java.util.List;
11
12 /**
13 * An {@link Executor} that provides methods to manage termination and
14 * methods that can produce a {@link Future} for tracking progress of
15 * one or more asynchronous tasks.
16 *
17 * <p>An {@code ExecutorService} can be shut down, which will cause
18 * it to reject new tasks. Two different methods are provided for
19 * shutting down an {@code ExecutorService}. The {@link #shutdown}
20 * method will allow previously submitted tasks to execute before
21 * terminating, while the {@link #shutdownNow} method prevents waiting
22 * tasks from starting and attempts to stop currently executing tasks.
23 * Upon termination, an executor has no tasks actively executing, no
24 * tasks awaiting execution, and no new tasks can be submitted. An
25 * unused {@code ExecutorService} should be shut down to allow
26 * reclamation of its resources.
27 *
28 * <p>Method {@code submit} extends base method {@link
29 * Executor#execute(Runnable)} by creating and returning a {@link Future}
30 * that can be used to cancel execution and/or wait for completion.
31 * Methods {@code invokeAny} and {@code invokeAll} perform the most
32 * commonly useful forms of bulk execution, executing a collection of
33 * tasks and then waiting for at least one, or all, to
34 * complete. (Class {@link ExecutorCompletionService} can be used to
35 * write customized variants of these methods.)
36 *
37 * <p>The {@link Executors} class provides factory methods for the
38 * executor services provided in this package.
39 *
40 * <h2>Usage Examples</h2>
41 *
42 * Here is a sketch of a network service in which threads in a thread
43 * pool service incoming requests. It uses the preconfigured {@link
44 * Executors#newFixedThreadPool} factory method:
45 *
46 * <pre> {@code
47 * class NetworkService implements Runnable {
48 * private final ServerSocket serverSocket;
49 * private final ExecutorService pool;
50 *
51 * public NetworkService(int port, int poolSize)
52 * throws IOException {
53 * serverSocket = new ServerSocket(port);
54 * pool = Executors.newFixedThreadPool(poolSize);
55 * }
56 *
57 * public void run() { // run the service
58 * try {
59 * for (;;) {
60 * pool.execute(new Handler(serverSocket.accept()));
61 * }
62 * } catch (IOException ex) {
63 * pool.shutdown();
64 * }
65 * }
66 * }
67 *
68 * class Handler implements Runnable {
69 * private final Socket socket;
70 * Handler(Socket socket) { this.socket = socket; }
71 * public void run() {
72 * // read and service request on socket
73 * }
74 * }}</pre>
75 *
76 * An {@code ExecutorService} may also be established and closed
77 * (shutdown, blocking until terminated) as follows; illustrating with
78 * a different {@code Executors} factory method:
79 *
80 * <pre> {@code
81 * try (ExecutorService e = Executors.newWorkStealingPool()) {
82 * // submit or execute many tasks with e ...
83 * }}</pre>
84 *
85 * Further customization is also possible. For example, the following
86 * method shuts down an {@code ExecutorService} in two phases, first
87 * by calling {@code shutdown} to reject incoming tasks, and then
88 * calling {@code shutdownNow}, if necessary, to cancel any lingering
89 * tasks:
90 *
91 * <pre> {@code
92 * void shutdownAndAwaitTermination(ExecutorService pool) {
93 * pool.shutdown(); // Disable new tasks from being submitted
94 * try {
95 * // Wait a while for existing tasks to terminate
96 * if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
97 * pool.shutdownNow(); // Cancel currently executing tasks
98 * // Wait a while for tasks to respond to being cancelled
99 * if (!pool.awaitTermination(60, TimeUnit.SECONDS))
100 * System.err.println("Pool did not terminate");
101 * }
102 * } catch (InterruptedException ex) {
103 * // (Re-)Cancel if current thread also interrupted
104 * pool.shutdownNow();
105 * // Preserve interrupt status
106 * Thread.currentThread().interrupt();
107 * }
108 * }}</pre>
109 *
110 * <p>Memory consistency effects: Actions in a thread prior to the
111 * submission of a {@code Runnable} or {@code Callable} task to an
112 * {@code ExecutorService}
113 * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
114 * any actions taken by that task, which in turn <i>happen-before</i> the
115 * result is retrieved via {@code Future.get()}.
116 *
117 * @since 1.5
118 * @author Doug Lea
119 */
120 public interface ExecutorService extends Executor, AutoCloseable {
121
122 /**
123 * Initiates an orderly shutdown in which previously submitted
124 * tasks are executed, but no new tasks will be accepted.
125 * Invocation has no additional effect if already shut down.
126 *
127 * <p>This method does not wait for previously submitted tasks to
128 * complete execution. Use {@link #awaitTermination awaitTermination}
129 * to do that.
130 *
131 * @throws SecurityException if a security manager exists and
132 * shutting down this ExecutorService may manipulate
133 * threads that the caller is not permitted to modify
134 * because it does not hold {@link
135 * java.lang.RuntimePermission}{@code ("modifyThread")},
136 * or the security manager's {@code checkAccess} method
137 * denies access.
138 */
139 void shutdown();
140
141 /**
142 * Attempts to stop all actively executing tasks, halts the
143 * processing of waiting tasks, and returns a list of the tasks
144 * that were awaiting execution.
145 *
146 * <p>This method does not wait for actively executing tasks to
147 * terminate. Use {@link #awaitTermination awaitTermination} to
148 * do that.
149 *
150 * <p>There are no guarantees beyond best-effort attempts to stop
151 * processing actively executing tasks. For example, typical
152 * implementations will cancel via {@link Thread#interrupt}, so any
153 * task that fails to respond to interrupts may never terminate.
154 *
155 * @return list of tasks that never commenced execution
156 * @throws SecurityException if a security manager exists and
157 * shutting down this ExecutorService may manipulate
158 * threads that the caller is not permitted to modify
159 * because it does not hold {@link
160 * java.lang.RuntimePermission}{@code ("modifyThread")},
161 * or the security manager's {@code checkAccess} method
162 * denies access.
163 */
164 List<Runnable> shutdownNow();
165
166 /**
167 * Returns {@code true} if this executor has been shut down.
168 *
169 * @return {@code true} if this executor has been shut down
170 */
171 boolean isShutdown();
172
173 /**
174 * Returns {@code true} if all tasks have completed following shut down.
175 * Note that {@code isTerminated} is never {@code true} unless
176 * either {@code shutdown} or {@code shutdownNow} was called first.
177 *
178 * @return {@code true} if all tasks have completed following shut down
179 */
180 boolean isTerminated();
181
182 /**
183 * Blocks until all tasks have completed execution after a shutdown
184 * request, or the timeout occurs, or the current thread is
185 * interrupted, whichever happens first.
186 *
187 * @param timeout the maximum time to wait
188 * @param unit the time unit of the timeout argument
189 * @return {@code true} if this executor terminated and
190 * {@code false} if the timeout elapsed before termination
191 * @throws InterruptedException if interrupted while waiting
192 */
193 boolean awaitTermination(long timeout, TimeUnit unit)
194 throws InterruptedException;
195
196 /**
197 * Submits a value-returning task for execution and returns a
198 * Future representing the pending results of the task. The
199 * Future's {@code get} method will return the task's result upon
200 * successful completion.
201 *
202 * <p>
203 * If you would like to immediately block waiting
204 * for a task, you can use constructions of the form
205 * {@code result = exec.submit(aCallable).get();}
206 *
207 * <p>Note: The {@link Executors} class includes a set of methods
208 * that can convert some other common closure-like objects,
209 * for example, {@link java.security.PrivilegedAction} to
210 * {@link Callable} form so they can be submitted.
211 *
212 * @param task the task to submit
213 * @param <T> the type of the task's result
214 * @return a Future representing pending completion of the task
215 * @throws RejectedExecutionException if the task cannot be
216 * scheduled for execution
217 * @throws NullPointerException if the task is null
218 */
219 <T> Future<T> submit(Callable<T> task);
220
221 /**
222 * Submits a Runnable task for execution and returns a Future
223 * representing that task. The Future's {@code get} method will
224 * return the given result upon successful completion.
225 *
226 * @param task the task to submit
227 * @param result the result to return
228 * @param <T> the type of the result
229 * @return a Future representing pending completion of the task
230 * @throws RejectedExecutionException if the task cannot be
231 * scheduled for execution
232 * @throws NullPointerException if the task is null
233 */
234 <T> Future<T> submit(Runnable task, T result);
235
236 /**
237 * Submits a Runnable task for execution and returns a Future
238 * representing that task. The Future's {@code get} method will
239 * return {@code null} upon <em>successful</em> completion.
240 *
241 * @param task the task to submit
242 * @return a Future representing pending completion of the task
243 * @throws RejectedExecutionException if the task cannot be
244 * scheduled for execution
245 * @throws NullPointerException if the task is null
246 */
247 Future<?> submit(Runnable task);
248
249 /**
250 * Executes the given tasks, returning a list of Futures holding
251 * their status and results when all complete.
252 * {@link Future#isDone} is {@code true} for each
253 * element of the returned list.
254 * Note that a <em>completed</em> task could have
255 * terminated either normally or by throwing an exception.
256 * The results of this method are undefined if the given
257 * collection is modified while this operation is in progress.
258 *
259 * @param tasks the collection of tasks
260 * @param <T> the type of the values returned from the tasks
261 * @return a list of Futures representing the tasks, in the same
262 * sequential order as produced by the iterator for the
263 * given task list, each of which has completed
264 * @throws InterruptedException if interrupted while waiting, in
265 * which case unfinished tasks are cancelled
266 * @throws NullPointerException if tasks or any of its elements are {@code null}
267 * @throws RejectedExecutionException if any task cannot be
268 * scheduled for execution
269 */
270 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
271 throws InterruptedException;
272
273 /**
274 * Executes the given tasks, returning a list of Futures holding
275 * their status and results
276 * when all complete or the timeout expires, whichever happens first.
277 * {@link Future#isDone} is {@code true} for each
278 * element of the returned list.
279 * Upon return, tasks that have not completed are cancelled.
280 * Note that a <em>completed</em> task could have
281 * terminated either normally or by throwing an exception.
282 * The results of this method are undefined if the given
283 * collection is modified while this operation is in progress.
284 *
285 * @param tasks the collection of tasks
286 * @param timeout the maximum time to wait
287 * @param unit the time unit of the timeout argument
288 * @param <T> the type of the values returned from the tasks
289 * @return a list of Futures representing the tasks, in the same
290 * sequential order as produced by the iterator for the
291 * given task list. If the operation did not time out,
292 * each task will have completed. If it did time out, some
293 * of these tasks will not have completed.
294 * @throws InterruptedException if interrupted while waiting, in
295 * which case unfinished tasks are cancelled
296 * @throws NullPointerException if tasks, any of its elements, or
297 * unit are {@code null}
298 * @throws RejectedExecutionException if any task cannot be scheduled
299 * for execution
300 */
301 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
302 long timeout, TimeUnit unit)
303 throws InterruptedException;
304
305 /**
306 * Executes the given tasks, returning the result
307 * of one that has completed successfully (i.e., without throwing
308 * an exception), if any do. Upon normal or exceptional return,
309 * tasks that have not completed are cancelled.
310 * The results of this method are undefined if the given
311 * collection is modified while this operation is in progress.
312 *
313 * @param tasks the collection of tasks
314 * @param <T> the type of the values returned from the tasks
315 * @return the result returned by one of the tasks
316 * @throws InterruptedException if interrupted while waiting
317 * @throws NullPointerException if tasks or any element task
318 * subject to execution is {@code null}
319 * @throws IllegalArgumentException if tasks is empty
320 * @throws ExecutionException if no task successfully completes
321 * @throws RejectedExecutionException if tasks cannot be scheduled
322 * for execution
323 */
324 <T> T invokeAny(Collection<? extends Callable<T>> tasks)
325 throws InterruptedException, ExecutionException;
326
327 /**
328 * Executes the given tasks, returning the result
329 * of one that has completed successfully (i.e., without throwing
330 * an exception), if any do before the given timeout elapses.
331 * Upon normal or exceptional return, tasks that have not
332 * completed are cancelled.
333 * The results of this method are undefined if the given
334 * collection is modified while this operation is in progress.
335 *
336 * @param tasks the collection of tasks
337 * @param timeout the maximum time to wait
338 * @param unit the time unit of the timeout argument
339 * @param <T> the type of the values returned from the tasks
340 * @return the result returned by one of the tasks
341 * @throws InterruptedException if interrupted while waiting
342 * @throws NullPointerException if tasks, or unit, or any element
343 * task subject to execution is {@code null}
344 * @throws TimeoutException if the given timeout elapses before
345 * any task successfully completes
346 * @throws ExecutionException if no task successfully completes
347 * @throws RejectedExecutionException if tasks cannot be scheduled
348 * for execution
349 */
350 <T> T invokeAny(Collection<? extends Callable<T>> tasks,
351 long timeout, TimeUnit unit)
352 throws InterruptedException, ExecutionException, TimeoutException;
353
354 /**
355 * Initiates an orderly shutdown in which previously submitted tasks are
356 * executed, but no new tasks will be accepted. This method waits until all
357 * tasks have completed execution and the executor has terminated.
358 *
359 * <p>If interrupted while waiting, this method stops all executing tasks as
360 * if by invoking {@link #shutdownNow()}. It then continues to wait until all
361 * actively executing tasks have completed. Tasks that were awaiting
362 * execution are not executed. The interrupt status will be re-asserted
363 * before this method returns.
364 *
365 * <p>If already terminated, invoking this method has no effect.
366 *
367 * @implSpec
368 * The default implementation invokes {@code shutdown()} and waits for tasks
369 * to complete execution with {@code awaitTermination}.
370 *
371 * @throws SecurityException if a security manager exists and
372 * shutting down this ExecutorService may manipulate
373 * threads that the caller is not permitted to modify
374 * because it does not hold {@link
375 * java.lang.RuntimePermission}{@code ("modifyThread")},
376 * or the security manager's {@code checkAccess} method
377 * denies access.
378 * @since 19
379 */
380 @Override
381 default void close() {
382 boolean terminated = isTerminated();
383 if (!terminated) {
384 shutdown();
385 boolean interrupted = false;
386 while (!terminated) {
387 try {
388 terminated = awaitTermination(1L, TimeUnit.DAYS);
389 } catch (InterruptedException e) {
390 if (!interrupted) {
391 shutdownNow();
392 interrupted = true;
393 }
394 }
395 }
396 if (interrupted) {
397 Thread.currentThread().interrupt();
398 }
399 }
400 }
401 }