5 |
|
*/ |
6 |
|
|
7 |
|
package java.util.concurrent; |
8 |
< |
|
8 |
> |
import java.util.concurrent.*; // for javadoc (till 6280605 is fixed) |
9 |
|
|
10 |
|
/** |
11 |
|
* A {@link CompletionService} that uses a supplied {@link Executor} |
25 |
|
* could write this as: |
26 |
|
* |
27 |
|
* <pre> |
28 |
< |
* void solve(Executor e, Collection<Callable<Result>> solvers) |
29 |
< |
* throws InterruptedException, ExecutionException { |
30 |
< |
* CompletionService<Result> ecs = new ExecutorCompletionService<Result>(e); |
31 |
< |
* for (Callable<Result> s : solvers) |
32 |
< |
* ecs.submit(s); |
33 |
< |
* int n = solvers.size(); |
34 |
< |
* for (int i = 0; i < n; ++i) { |
35 |
< |
* Result r = ecs.take().get(); |
36 |
< |
* if (r != null) |
37 |
< |
* use(r); |
38 |
< |
* } |
39 |
< |
* } |
28 |
> |
* void solve(Executor e, |
29 |
> |
* Collection<Callable<Result>> solvers) |
30 |
> |
* throws InterruptedException, ExecutionException { |
31 |
> |
* CompletionService<Result> ecs |
32 |
> |
* = new ExecutorCompletionService<Result>(e); |
33 |
> |
* for (Callable<Result> s : solvers) |
34 |
> |
* ecs.submit(s); |
35 |
> |
* int n = solvers.size(); |
36 |
> |
* for (int i = 0; i < n; ++i) { |
37 |
> |
* Result r = ecs.take().get(); |
38 |
> |
* if (r != null) |
39 |
> |
* use(r); |
40 |
> |
* } |
41 |
> |
* } |
42 |
|
* </pre> |
43 |
|
* |
44 |
|
* Suppose instead that you would like to use the first non-null result |
46 |
|
* and cancelling all other tasks when the first one is ready: |
47 |
|
* |
48 |
|
* <pre> |
49 |
< |
* void solve(Executor e, Collection<Callable<Result>> solvers) |
50 |
< |
* throws InterruptedException { |
51 |
< |
* CompletionService<Result> ecs = new ExecutorCompletionService<Result>(e); |
52 |
< |
* int n = solvers.size(); |
53 |
< |
* List<Future<Result>> futures = new ArrayList<Future<Result>>(n); |
54 |
< |
* Result result = null; |
55 |
< |
* try { |
56 |
< |
* for (Callable<Result> s : solvers) |
57 |
< |
* futures.add(ecs.submit(s)); |
58 |
< |
* for (int i = 0; i < n; ++i) { |
59 |
< |
* try { |
60 |
< |
* Result r = ecs.take().get(); |
61 |
< |
* if (r != null) { |
62 |
< |
* result = r; |
63 |
< |
* break; |
64 |
< |
* } |
65 |
< |
* } catch (ExecutionException ignore) {} |
66 |
< |
* } |
67 |
< |
* } |
68 |
< |
* finally { |
69 |
< |
* for (Future<Result> f : futures) |
70 |
< |
* f.cancel(true); |
71 |
< |
* } |
72 |
< |
* |
73 |
< |
* if (result != null) |
74 |
< |
* use(result); |
75 |
< |
* } |
49 |
> |
* void solve(Executor e, |
50 |
> |
* Collection<Callable<Result>> solvers) |
51 |
> |
* throws InterruptedException { |
52 |
> |
* CompletionService<Result> ecs |
53 |
> |
* = new ExecutorCompletionService<Result>(e); |
54 |
> |
* int n = solvers.size(); |
55 |
> |
* List<Future<Result>> futures |
56 |
> |
* = new ArrayList<Future<Result>>(n); |
57 |
> |
* Result result = null; |
58 |
> |
* try { |
59 |
> |
* for (Callable<Result> s : solvers) |
60 |
> |
* futures.add(ecs.submit(s)); |
61 |
> |
* for (int i = 0; i < n; ++i) { |
62 |
> |
* try { |
63 |
> |
* Result r = ecs.take().get(); |
64 |
> |
* if (r != null) { |
65 |
> |
* result = r; |
66 |
> |
* break; |
67 |
> |
* } |
68 |
> |
* } catch (ExecutionException ignore) {} |
69 |
> |
* } |
70 |
> |
* } |
71 |
> |
* finally { |
72 |
> |
* for (Future<Result> f : futures) |
73 |
> |
* f.cancel(true); |
74 |
> |
* } |
75 |
> |
* |
76 |
> |
* if (result != null) |
77 |
> |
* use(result); |
78 |
> |
* } |
79 |
|
* </pre> |
80 |
|
*/ |
81 |
|
public class ExecutorCompletionService<V> implements CompletionService<V> { |
113 |
|
* Creates an ExecutorCompletionService using the supplied |
114 |
|
* executor for base task execution and a |
115 |
|
* {@link LinkedBlockingQueue} as a completion queue. |
116 |
+ |
* |
117 |
|
* @param executor the executor to use |
118 |
|
* @throws NullPointerException if executor is <tt>null</tt> |
119 |
|
*/ |
130 |
|
* Creates an ExecutorCompletionService using the supplied |
131 |
|
* executor for base task execution and the supplied queue as its |
132 |
|
* completion queue. |
133 |
+ |
* |
134 |
|
* @param executor the executor to use |
135 |
|
* @param completionQueue the queue to use as the completion queue |
136 |
|
* normally one dedicated for use by this service |