ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/AbstractExecutorService.java
Revision: 1.48
Committed: Wed Dec 3 21:55:44 2014 UTC (9 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.47: +5 -1 lines
Log Message:
never use wildcard imports

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