ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/AbstractExecutorService.java
Revision: 1.53
Committed: Fri Jul 24 20:54:37 2020 UTC (3 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.52: +5 -0 lines
Log Message:
8250240: Address use of default constructors in the java.util.concurrent

File Contents

# User Rev Content
1 tim 1.1 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3 dl 1.17 * Expert Group and released to the public domain, as explained at
4 jsr166 1.35 * http://creativecommons.org/publicdomain/zero/1.0/
5 tim 1.1 */
6    
7     package java.util.concurrent;
8 jsr166 1.48
9 jsr166 1.49 import static java.util.concurrent.TimeUnit.NANOSECONDS;
10 jsr166 1.50
11 jsr166 1.48 import java.util.ArrayList;
12     import java.util.Collection;
13     import java.util.Iterator;
14     import java.util.List;
15 tim 1.1
16     /**
17 jsr166 1.24 * Provides default implementations of {@link ExecutorService}
18 jsr166 1.40 * execution methods. This class implements the {@code submit},
19     * {@code invokeAny} and {@code invokeAll} methods using a
20     * {@link RunnableFuture} returned by {@code newTaskFor}, which defaults
21 peierls 1.21 * to the {@link FutureTask} class provided in this package. For example,
22 jsr166 1.40 * the implementation of {@code submit(Runnable)} creates an
23     * associated {@code RunnableFuture} that is executed and
24     * returned. Subclasses may override the {@code newTaskFor} methods
25     * to return {@code RunnableFuture} implementations other than
26     * {@code FutureTask}.
27 tim 1.1 *
28 jsr166 1.39 * <p><b>Extension example</b>. Here is a sketch of a class
29 dl 1.22 * that customizes {@link ThreadPoolExecutor} to use
30 jsr166 1.40 * a {@code CustomTask} class instead of the default {@code FutureTask}:
31 jsr166 1.51 * <pre> {@code
32 dl 1.22 * public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
33     *
34 jsr166 1.32 * static class CustomTask<V> implements RunnableFuture<V> {...}
35 dl 1.22 *
36 jsr166 1.32 * protected <V> RunnableFuture<V> newTaskFor(Callable<V> c) {
37     * return new CustomTask<V>(c);
38 jsr166 1.25 * }
39 jsr166 1.32 * protected <V> RunnableFuture<V> newTaskFor(Runnable r, V v) {
40     * return new CustomTask<V>(r, v);
41 jsr166 1.25 * }
42     * // ... add constructors, etc.
43 jsr166 1.32 * }}</pre>
44     *
45 tim 1.1 * @since 1.5
46     * @author Doug Lea
47     */
48     public abstract class AbstractExecutorService implements ExecutorService {
49    
50 peierls 1.21 /**
51 jsr166 1.53 * Constructor for subclasses to call.
52     */
53     public AbstractExecutorService() {}
54    
55     /**
56 jsr166 1.40 * Returns a {@code RunnableFuture} for the given runnable and default
57 peierls 1.21 * value.
58 jsr166 1.24 *
59 peierls 1.21 * @param runnable the runnable task being wrapped
60     * @param value the default value for the returned future
61 jsr166 1.46 * @param <T> the type of the given value
62 jsr166 1.44 * @return a {@code RunnableFuture} which, when run, will run the
63 jsr166 1.40 * underlying runnable and which, as a {@code Future}, will yield
64 dl 1.22 * the given value as its result and provide for cancellation of
65 jsr166 1.43 * the underlying task
66 dl 1.22 * @since 1.6
67 peierls 1.21 */
68     protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
69     return new FutureTask<T>(runnable, value);
70     }
71    
72     /**
73 jsr166 1.40 * Returns a {@code RunnableFuture} for the given callable task.
74 jsr166 1.24 *
75 peierls 1.21 * @param callable the callable task being wrapped
76 jsr166 1.46 * @param <T> the type of the callable's result
77 jsr166 1.44 * @return a {@code RunnableFuture} which, when run, will call the
78 jsr166 1.40 * underlying callable and which, as a {@code Future}, will yield
79 dl 1.22 * the callable's result as its result and provide for
80 jsr166 1.43 * cancellation of the underlying task
81 dl 1.22 * @since 1.6
82 peierls 1.21 */
83     protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
84     return new FutureTask<T>(callable);
85     }
86    
87 jsr166 1.30 /**
88     * @throws RejectedExecutionException {@inheritDoc}
89     * @throws NullPointerException {@inheritDoc}
90     */
91 dl 1.11 public Future<?> submit(Runnable task) {
92 dl 1.13 if (task == null) throw new NullPointerException();
93 jsr166 1.33 RunnableFuture<Void> ftask = newTaskFor(task, null);
94 tim 1.1 execute(ftask);
95     return ftask;
96     }
97    
98 jsr166 1.30 /**
99     * @throws RejectedExecutionException {@inheritDoc}
100     * @throws NullPointerException {@inheritDoc}
101     */
102 dl 1.13 public <T> Future<T> submit(Runnable task, T result) {
103     if (task == null) throw new NullPointerException();
104 peierls 1.21 RunnableFuture<T> ftask = newTaskFor(task, result);
105 dl 1.13 execute(ftask);
106     return ftask;
107     }
108    
109 jsr166 1.30 /**
110     * @throws RejectedExecutionException {@inheritDoc}
111     * @throws NullPointerException {@inheritDoc}
112     */
113 tim 1.1 public <T> Future<T> submit(Callable<T> task) {
114 dl 1.13 if (task == null) throw new NullPointerException();
115 peierls 1.21 RunnableFuture<T> ftask = newTaskFor(task);
116 tim 1.1 execute(ftask);
117     return ftask;
118     }
119    
120 dl 1.15 /**
121     * the main mechanics of invokeAny.
122     */
123 jsr166 1.26 private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
124 jsr166 1.36 boolean timed, long nanos)
125 dl 1.15 throws InterruptedException, ExecutionException, TimeoutException {
126 dl 1.3 if (tasks == null)
127     throw new NullPointerException();
128 dl 1.15 int ntasks = tasks.size();
129     if (ntasks == 0)
130 dl 1.7 throw new IllegalArgumentException();
131 jsr166 1.47 ArrayList<Future<T>> futures = new ArrayList<>(ntasks);
132 jsr166 1.20 ExecutorCompletionService<T> ecs =
133 dl 1.7 new ExecutorCompletionService<T>(this);
134 dl 1.15
135     // For efficiency, especially in executors with limited
136     // parallelism, check to see if previously submitted tasks are
137 dl 1.18 // done before submitting more of them. This interleaving
138 dl 1.15 // plus the exception mechanics account for messiness of main
139 dl 1.18 // loop.
140 dl 1.15
141 dl 1.3 try {
142 dl 1.15 // Record exceptions so that if we fail to obtain any
143     // result, we can throw the last exception we got.
144 dl 1.7 ExecutionException ee = null;
145 jsr166 1.37 final long deadline = timed ? System.nanoTime() + nanos : 0L;
146 jsr166 1.26 Iterator<? extends Callable<T>> it = tasks.iterator();
147 dl 1.15
148     // Start one task for sure; the rest incrementally
149     futures.add(ecs.submit(it.next()));
150     --ntasks;
151     int active = 1;
152    
153     for (;;) {
154 jsr166 1.20 Future<T> f = ecs.poll();
155 dl 1.15 if (f == null) {
156     if (ntasks > 0) {
157     --ntasks;
158     futures.add(ecs.submit(it.next()));
159     ++active;
160     }
161 jsr166 1.20 else if (active == 0)
162 dl 1.15 break;
163     else if (timed) {
164 jsr166 1.49 f = ecs.poll(nanos, NANOSECONDS);
165 dl 1.15 if (f == null)
166     throw new TimeoutException();
167 jsr166 1.37 nanos = deadline - System.nanoTime();
168 dl 1.15 }
169 jsr166 1.20 else
170 dl 1.15 f = ecs.take();
171     }
172     if (f != null) {
173     --active;
174     try {
175     return f.get();
176 jsr166 1.19 } catch (ExecutionException eex) {
177 dl 1.15 ee = eex;
178 jsr166 1.19 } catch (RuntimeException rex) {
179 dl 1.15 ee = new ExecutionException(rex);
180     }
181 dl 1.7 }
182 jsr166 1.20 }
183 dl 1.15
184     if (ee == null)
185     ee = new ExecutionException();
186     throw ee;
187    
188 dl 1.3 } finally {
189 jsr166 1.49 cancelAll(futures);
190 dl 1.3 }
191     }
192    
193 jsr166 1.26 public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
194 dl 1.15 throws InterruptedException, ExecutionException {
195     try {
196     return doInvokeAny(tasks, false, 0);
197     } catch (TimeoutException cannotHappen) {
198     assert false;
199     return null;
200     }
201     }
202    
203 jsr166 1.26 public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
204 jsr166 1.20 long timeout, TimeUnit unit)
205 dl 1.7 throws InterruptedException, ExecutionException, TimeoutException {
206 dl 1.15 return doInvokeAny(tasks, true, unit.toNanos(timeout));
207 dl 1.3 }
208    
209 jsr166 1.26 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
210 dl 1.3 throws InterruptedException {
211     if (tasks == null)
212     throw new NullPointerException();
213 jsr166 1.47 ArrayList<Future<T>> futures = new ArrayList<>(tasks.size());
214 dl 1.3 try {
215     for (Callable<T> t : tasks) {
216 peierls 1.21 RunnableFuture<T> f = newTaskFor(t);
217 dl 1.3 futures.add(f);
218     execute(f);
219     }
220 jsr166 1.42 for (int i = 0, size = futures.size(); i < size; i++) {
221     Future<T> f = futures.get(i);
222 dl 1.6 if (!f.isDone()) {
223 jsr166 1.49 try { f.get(); }
224 jsr166 1.52 catch (CancellationException | ExecutionException ignore) {}
225 dl 1.6 }
226     }
227 dl 1.3 return futures;
228 jsr166 1.49 } catch (Throwable t) {
229     cancelAll(futures);
230     throw t;
231 dl 1.3 }
232     }
233    
234 jsr166 1.26 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
235 jsr166 1.20 long timeout, TimeUnit unit)
236 dl 1.3 throws InterruptedException {
237 jsr166 1.38 if (tasks == null)
238 dl 1.3 throw new NullPointerException();
239 jsr166 1.49 final long nanos = unit.toNanos(timeout);
240     final long deadline = System.nanoTime() + nanos;
241 jsr166 1.47 ArrayList<Future<T>> futures = new ArrayList<>(tasks.size());
242 jsr166 1.49 int j = 0;
243     timedOut: try {
244 jsr166 1.20 for (Callable<T> t : tasks)
245 peierls 1.21 futures.add(newTaskFor(t));
246 dl 1.16
247 jsr166 1.42 final int size = futures.size();
248 dl 1.16
249     // Interleave time checks and calls to execute in case
250     // executor doesn't have any/much parallelism.
251 jsr166 1.42 for (int i = 0; i < size; i++) {
252 jsr166 1.49 if (((i == 0) ? nanos : deadline - System.nanoTime()) <= 0L)
253     break timedOut;
254 jsr166 1.42 execute((Runnable)futures.get(i));
255 dl 1.3 }
256 dl 1.16
257 jsr166 1.49 for (; j < size; j++) {
258     Future<T> f = futures.get(j);
259 dl 1.6 if (!f.isDone()) {
260 jsr166 1.49 try { f.get(deadline - System.nanoTime(), NANOSECONDS); }
261 jsr166 1.52 catch (CancellationException | ExecutionException ignore) {}
262 jsr166 1.49 catch (TimeoutException timedOut) {
263     break timedOut;
264 dl 1.6 }
265     }
266     }
267 dl 1.3 return futures;
268 jsr166 1.49 } catch (Throwable t) {
269     cancelAll(futures);
270     throw t;
271 dl 1.3 }
272 jsr166 1.49 // Timed out before all the tasks could be completed; cancel remaining
273     cancelAll(futures, j);
274     return futures;
275 dl 1.3 }
276    
277 jsr166 1.49 private static <T> void cancelAll(ArrayList<Future<T>> futures) {
278     cancelAll(futures, 0);
279     }
280    
281     /** Cancels all futures with index at least j. */
282     private static <T> void cancelAll(ArrayList<Future<T>> futures, int j) {
283     for (int size = futures.size(); j < size; j++)
284     futures.get(j).cancel(true);
285     }
286 tim 1.1 }