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/licenses/publicdomain
7 package java.util.concurrent;
9 import java.util.ArrayList;
10 import java.util.Collection;
11 import java.util.Iterator;
12 import java.util.List;
15 * Provides default implementations of {@link ExecutorService}
16 * execution methods. This class implements the <tt>submit</tt>,
17 * <tt>invokeAny</tt> and <tt>invokeAll</tt> methods using a
18 * {@link RunnableFuture} returned by <tt>newTaskFor</tt>, which defaults
19 * to the {@link FutureTask} class provided in this package. For example,
20 * the implementation of <tt>submit(Runnable)</tt> creates an
21 * associated <tt>RunnableFuture</tt> that is executed and
22 * returned. Subclasses may override the <tt>newTaskFor</tt> methods
23 * to return <tt>RunnableFuture</tt> implementations other than
24 * <tt>FutureTask</tt>.
26 * <p> <b>Extension example</b>. Here is a sketch of a class
27 * that customizes {@link ThreadPoolExecutor} to use
28 * a <tt>CustomTask</tt> class instead of the default <tt>FutureTask</tt>:
30 * public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
32 * static class CustomTask<V> implements RunnableFuture<V> {...}
34 * protected <V> RunnableFuture<V> newTaskFor(Callable<V> c) {
35 * return new CustomTask<V>(c);
37 * protected <V> RunnableFuture<V> newTaskFor(Runnable r, V v) {
38 * return new CustomTask<V>(r, v);
40 * // ... add constructors, etc.
46 public abstract class AbstractExecutorService implements ExecutorService {
49 * Returns a <tt>RunnableFuture</tt> for the given runnable and default
52 * @param runnable the runnable task being wrapped
53 * @param value the default value for the returned future
54 * @return a <tt>RunnableFuture</tt> which when run will run the
55 * underlying runnable and which, as a <tt>Future</tt>, will yield
56 * the given value as its result and provide for cancellation of
57 * the underlying task.
60 protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
61 return new FutureTask<T>(runnable, value);
65 * Returns a <tt>RunnableFuture</tt> for the given callable task.
67 * @param callable the callable task being wrapped
68 * @return a <tt>RunnableFuture</tt> which when run will call the
69 * underlying callable and which, as a <tt>Future</tt>, will yield
70 * the callable's result as its result and provide for
71 * cancellation of the underlying task.
74 protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
75 return new FutureTask<T>(callable);
79 * @throws RejectedExecutionException {@inheritDoc}
80 * @throws NullPointerException {@inheritDoc}
82 public Future<?> submit(Runnable task) {
83 if (task == null) throw new NullPointerException();
84 RunnableFuture<Object> ftask = newTaskFor(task, null);
90 * @throws RejectedExecutionException {@inheritDoc}
91 * @throws NullPointerException {@inheritDoc}
93 public <T> Future<T> submit(Runnable task, T result) {
94 if (task == null) throw new NullPointerException();
95 RunnableFuture<T> ftask = newTaskFor(task, result);
101 * @throws RejectedExecutionException {@inheritDoc}
102 * @throws NullPointerException {@inheritDoc}
104 public <T> Future<T> submit(Callable<T> task) {
105 if (task == null) throw new NullPointerException();
106 RunnableFuture<T> ftask = newTaskFor(task);
112 * the main mechanics of invokeAny.
114 private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
115 boolean timed, long nanos)
116 throws InterruptedException, ExecutionException, TimeoutException {
118 throw new NullPointerException();
119 int ntasks = tasks.size();
121 throw new IllegalArgumentException();
122 List<Future<T>> futures= new ArrayList<Future<T>>(ntasks);
123 ExecutorCompletionService<T> ecs =
124 new ExecutorCompletionService<T>(this);
126 // For efficiency, especially in executors with limited
127 // parallelism, check to see if previously submitted tasks are
128 // done before submitting more of them. This interleaving
129 // plus the exception mechanics account for messiness of main
133 // Record exceptions so that if we fail to obtain any
134 // result, we can throw the last exception we got.
135 ExecutionException ee = null;
136 long lastTime = (timed)? System.nanoTime() : 0;
137 Iterator<? extends Callable<T>> it = tasks.iterator();
139 // Start one task for sure; the rest incrementally
140 futures.add(ecs.submit(it.next()));
145 Future<T> f = ecs.poll();
149 futures.add(ecs.submit(it.next()));
152 else if (active == 0)
155 f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
157 throw new TimeoutException();
158 long now = System.nanoTime();
159 nanos -= now - lastTime;
169 } catch (InterruptedException ie) {
171 } catch (ExecutionException eex) {
173 } catch (RuntimeException rex) {
174 ee = new ExecutionException(rex);
180 ee = new ExecutionException();
184 for (Future<T> f : futures)
189 public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
190 throws InterruptedException, ExecutionException {
192 return doInvokeAny(tasks, false, 0);
193 } catch (TimeoutException cannotHappen) {
199 public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
200 long timeout, TimeUnit unit)
201 throws InterruptedException, ExecutionException, TimeoutException {
202 return doInvokeAny(tasks, true, unit.toNanos(timeout));
205 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
206 throws InterruptedException {
208 throw new NullPointerException();
209 List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
210 boolean done = false;
212 for (Callable<T> t : tasks) {
213 RunnableFuture<T> f = newTaskFor(t);
217 for (Future<T> f : futures) {
221 } catch (CancellationException ignore) {
222 } catch (ExecutionException ignore) {
230 for (Future<T> f : futures)
235 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
236 long timeout, TimeUnit unit)
237 throws InterruptedException {
238 if (tasks == null || unit == null)
239 throw new NullPointerException();
240 long nanos = unit.toNanos(timeout);
241 List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
242 boolean done = false;
244 for (Callable<T> t : tasks)
245 futures.add(newTaskFor(t));
247 long lastTime = System.nanoTime();
249 // Interleave time checks and calls to execute in case
250 // executor doesn't have any/much parallelism.
251 Iterator<Future<T>> it = futures.iterator();
252 while (it.hasNext()) {
253 execute((Runnable)(it.next()));
254 long now = System.nanoTime();
255 nanos -= now - lastTime;
261 for (Future<T> f : futures) {
266 f.get(nanos, TimeUnit.NANOSECONDS);
267 } catch (CancellationException ignore) {
268 } catch (ExecutionException ignore) {
269 } catch (TimeoutException toe) {
272 long now = System.nanoTime();
273 nanos -= now - lastTime;
281 for (Future<T> f : futures)