KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > util > concurrent > ExecutorCompletionService


1 /*
2  * @(#)ExecutorCompletionService.java 1.1 04/02/09
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.util.concurrent;
9
10
11 /**
12  * A {@link CompletionService} that uses a supplied {@link Executor}
13  * to execute tasks. This class arranges that submitted tasks are,
14  * upon completion, placed on a queue accessible using <tt>take</tt>.
15  * The class is lightweight enough to be suitable for transient use
16  * when processing groups of tasks.
17  *
18  * <p>
19  *
20  * <b>Usage Examples.</b>
21  *
22  * Suppose you have a set of solvers for a certain problem, each
23  * returning a value of some type <tt>Result</tt>, and would like to
24  * run them concurrently, processing the results of each of them that
25  * return a non-null value, in some method <tt>use(Result r)</tt>. You
26  * could write this as:
27  *
28  * <pre>
29  * void solve(Executor e, Collection&lt;Callable&lt;Result&gt;&gt; solvers)
30  * throws InterruptedException, ExecutionException {
31  * CompletionService&lt;Result&gt; ecs = new ExecutorCompletionService&lt;Result&gt;(e);
32  * for (Callable&lt;Result&gt; s : solvers)
33  * ecs.submit(s);
34  * int n = solvers.size();
35  * for (int i = 0; i &lt; n; ++i) {
36  * Result r = ecs.take().get();
37  * if (r != null)
38  * use(r);
39  * }
40  * }
41  * </pre>
42  *
43  * Suppose instead that you would like to use the first non-null result
44  * of the set of tasks, ignoring any that encounter exceptions,
45  * and cancelling all other tasks when the first one is ready:
46  *
47  * <pre>
48  * void solve(Executor e, Collection&lt;Callable&lt;Result&gt;&gt; solvers)
49  * throws InterruptedException {
50  * CompletionService&lt;Result&gt; ecs = new ExecutorCompletionService&lt;Result&gt;(e);
51  * int n = solvers.size();
52  * List&lt;Future&lt;Result&gt;&gt; futures = new ArrayList&lt;Future&lt;Result&gt;&gt;(n);
53  * Result result = null;
54  * try {
55  * for (Callable&lt;Result&gt; s : solvers)
56  * futures.add(ecs.submit(s));
57  * for (int i = 0; i &lt; n; ++i) {
58  * try {
59  * Result r = ecs.take().get();
60  * if (r != null) {
61  * result = r;
62  * break;
63  * }
64  * } catch(ExecutionException ignore) {}
65  * }
66  * }
67  * finally {
68  * for (Future&lt;Result&gt; f : futures)
69  * f.cancel(true);
70  * }
71  *
72  * if (result != null)
73  * use(result);
74  * }
75  * </pre>
76  */

77 public class ExecutorCompletionService<V> implements CompletionService JavaDoc<V> {
78     private final Executor JavaDoc executor;
79     private final BlockingQueue JavaDoc<Future JavaDoc<V>> completionQueue;
80
81     /**
82      * FutureTask extension to enqueue upon completion
83      */

84     private class QueueingFuture extends FutureTask JavaDoc<V> {
85         QueueingFuture(Callable JavaDoc<V> c) { super(c); }
86         QueueingFuture(Runnable JavaDoc t, V r) { super(t, r); }
87         protected void done() { completionQueue.add(this); }
88     }
89
90     /**
91      * Creates an ExecutorCompletionService using the supplied
92      * executor for base task execution and a
93      * {@link LinkedBlockingQueue} as a completion queue.
94      * @param executor the executor to use
95      * @throws NullPointerException if executor is <tt>null</tt>
96      */

97     public ExecutorCompletionService(Executor JavaDoc executor) {
98         if (executor == null)
99             throw new NullPointerException JavaDoc();
100         this.executor = executor;
101         this.completionQueue = new LinkedBlockingQueue JavaDoc<Future JavaDoc<V>>();
102     }
103
104     /**
105      * Creates an ExecutorCompletionService using the supplied
106      * executor for base task execution and the supplied queue as its
107      * completion queue.
108      * @param executor the executor to use
109      * @param completionQueue the queue to use as the completion queue
110      * normally one dedicated for use by this service
111      * @throws NullPointerException if executor or completionQueue are <tt>null</tt>
112      */

113     public ExecutorCompletionService(Executor JavaDoc executor,
114                                      BlockingQueue JavaDoc<Future JavaDoc<V>> completionQueue) {
115         if (executor == null || completionQueue == null)
116             throw new NullPointerException JavaDoc();
117         this.executor = executor;
118         this.completionQueue = completionQueue;
119     }
120
121     public Future JavaDoc<V> submit(Callable JavaDoc<V> task) {
122         if (task == null) throw new NullPointerException JavaDoc();
123         QueueingFuture f = new QueueingFuture(task);
124         executor.execute(f);
125         return f;
126     }
127
128     public Future JavaDoc<V> submit(Runnable JavaDoc task, V result) {
129         if (task == null) throw new NullPointerException JavaDoc();
130         QueueingFuture f = new QueueingFuture(task, result);
131         executor.execute(f);
132         return f;
133     }
134
135     public Future JavaDoc<V> take() throws InterruptedException JavaDoc {
136         return completionQueue.take();
137     }
138
139     public Future JavaDoc<V> poll() {
140         return completionQueue.poll();
141     }
142
143     public Future JavaDoc<V> poll(long timeout, TimeUnit JavaDoc unit) throws InterruptedException JavaDoc {
144         return completionQueue.poll(timeout, unit);
145     }
146
147 }
148
149
150
Popular Tags