View Javadoc

1   /**
2    *  Licensed to the Apache Software Foundation (ASF) under one or more
3    *  contributor license agreements.  See the NOTICE file distributed with
4    *  this work for additional information regarding copyright ownership.
5    *  The ASF licenses this file to You under the Apache License, Version 2.0
6    *  (the "License"); you may not use this file except in compliance with
7    *  the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  package javax.util.concurrent;
18  
19  import java.util.Collection;
20  import java.util.List;
21  import java.util.concurrent.Callable;
22  import java.util.concurrent.ExecutionException;
23  import java.util.concurrent.ExecutorService;
24  import java.util.concurrent.Future;
25  import java.util.concurrent.RejectedExecutionException;
26  import java.util.concurrent.TimeUnit;
27  import java.util.concurrent.TimeoutException;
28  
29  
30  
31  /**
32   * A manageable version of a {@link java.util.concurrent.ExecutorService}.<p>
33   *
34   * A ManagedExecutorService provides methods for submitting tasks for execution
35   * in a managed environment.  Implementations of the ManagedExecutorService are
36   * provided by a Java&trade; EE Product Provider.  Application Component Providers
37   * use the Java Naming and Directory Interface&trade; (JNDI) to look-up instances of one
38   * or more ManagedExecutorService objects using resource environment references.<p>
39   *
40   * The Concurrency Utilities for Java&trade; EE specification describes several
41   * behaviors that a ManagedExecutorService can implement.  The Application
42   * Component Provider and Deployer identify these requirements and map the
43   * resource environment reference appropriately.<p>
44   *
45   * The most common uses for a ManagedExecutorService is to run short-duration asynchronous
46   * tasks in the local JVM from a container such as an Enterprise
47   * JavaBean&trade; (EJB&trade;) or servlet.  Use a managed ThreadFactory for long-running
48   * daemon tasks.<p>
49   *
50   * Tasks run within the application component context that either
51   * submitted the task or created the ManagedExecutorService instance (server-managed or component-managed).
52   * All tasks run without an explicit transaction (they do not enlist in the application
53   * component's transaction).  If a transaction is required, use a
54   * {@link javax.transaction.UserTransaction} instance.  A UserTransaction instance is
55   * available in JNDI using the name: &QUOT;java:comp/UserTransaction&QUOT<p>
56   *
57   * Example:<pre>
58   * public run() {
59   *     // Begin of task
60   *     InitialContext ctx = new InitialContext();
61   *     UserTransaction ut = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
62   *     ut.begin();
63   *
64   *     // Perform transactional business logic
65   *
66   *     ut.commit();
67   * }</PRE>
68   *
69   * Asynchronous tasks are typically submitted to the ManagedExecutorService using one
70   * of the <code>submit</code> methods, each of which return a {@link java.util.concurrent.Future}
71   * instance.  The <code>Future</code> represents the result of the task and can also be used to
72   * check if the task is complete or wait for its completion.<p>
73   *
74   * If the task is cancelled, the result fo the task is a
75   * {@link java.util.concurrent.CancellationException} exception.  If the task is unable
76   * to run due to start due to a reason other than cancellation, the result is a
77   * {@link javax.util.concurrent.AbortedException} exception.<p>
78   *
79   * Example:<pre>
80   * &#47;**
81   *  * Retrieve all accounts from several account databases in parallel.
82   *  * Resource Mappings:
83   *  *  type:      javax.util.concurrent.ManagedExecutorService
84   *  *  jndi-name: mes/ThreadPool
85   *  *  attributes:
86   *  *    Run Location = Local
87   *  *&#47;
88   * public List<Account> getAccounts(long accountId) {
89   *     try {
90   *         javax.naming.InitialContext ctx = new InitialContext();
91   *         <b>ManagedExecutorService mes = (ManagedExecutorService)
92   *             ctx.lookup("java:comp/env/concurrent/ThreadPool");</b>
93   *
94   *         // Create a set of tasks to perform the account retrieval.
95   *         ArrayList<Callable<Account>> retrieverTasks = new ArrayList<Callable<Account>>();
96   *         retrieverTasks.add(new EISAccountRetriever());
97   *         retrieverTasks.add(new RDBAccountRetriever());
98   *
99   *         // Submit the tasks to the thread pool and wait for them
100  *         // to complete (successfully or otherwise).
101  *         <b>List<Future<Account>> taskResults= mes.invokeAll(retrieverTasks);</b>
102  *
103  *         // Retrieve the results from the resulting Future list.
104  *         ArrayList<Account> results = new ArrayList<Account>();
105  *         for(Future<Account> taskResult : taskResults) {
106  *             try {
107  *                 <b>results.add(taskResult.get());</b>
108  *             } catch (ExecutionException e) {
109  *                 Throwable cause = e.getCause();
110  *                 // Handle the AccountRetrieverError.
111  *             }
112  *         }
113  *
114  *         return results;
115  *
116  *     } catch (NamingException e) {
117  *         // Throw exception for fatal error.
118  *     } catch (InterruptedException e) {
119  *         // Throw exception for shutdown or other interrupt condition.
120  *     }
121  *   }
122  *
123  * }
124  *
125  * public class EISAccountRetriever implements Callable<Account> {
126  *     public Account call() {
127  *         // Connect to our eis system and retrieve the info for the account.
128  *         //...
129  *         return null;
130  *     }
131  * }
132  *
133  * public class RDBAccountRetriever implements Callable<Account> {
134  *     public Account call() {
135  *         // Connect to our database and retrieve the info for the account.
136  *         //...
137  *     }
138  * }
139  *
140  * public class Account {
141  *     // Some account data...
142  * }
143  *
144  *</pre>
145  */
146 public interface ManagedExecutorService extends ExecutorService
147 {
148     /**
149      * This method has the same semantics as {@link ExecutorService#submit(java.lang.Runnable)}
150      * but also includes the ability to be notified when the task's lifecycle changes.
151      *
152      * @param task the task to submit
153      * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
154      * @return a Future representing pending completion of the task,
155      * and whose <tt>get()</tt> method will return <tt>null</tt>
156      * upon completion.
157      * @throws RejectedExecutionException if task cannot be scheduled
158      * for execution
159      * @throws NullPointerException if task null
160      */
161     Future<?> submit(Runnable task, ManagedTaskListener taskListener);
162 
163     /**
164      * This method has the same semantics as {@link ExecutorService#submit(java.lang.Runnable, T)}
165      * but also includes the ability to be notified when the task's lifecycle changes.
166      *
167      * @param task the task to submit
168      * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
169      * @param result the result to return
170      * @return a Future representing pending completion of the task,
171      * and whose <tt>get()</tt> method will return the given result
172      * upon completion.
173      * @throws RejectedExecutionException if task cannot be scheduled
174      * for execution
175      * @throws NullPointerException if task null
176      */
177     <T> Future<T> submit(Runnable task, T result, ManagedTaskListener taskListener);
178 
179     /**
180      * This method has the same semantics as {@link ExecutorService#submit(java.util.concurrent.Callable)}
181      * but also includes the ability to be notified when the task's lifecycle changes.
182      *
183      * @param task the task to submit
184      * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
185      * @return a Future representing pending completion of the task
186      * @throws RejectedExecutionException if task cannot be scheduled
187      * for execution
188      * @throws NullPointerException if task null
189      */
190     <T> Future<T> submit(Callable<T> task, ManagedTaskListener taskListener);
191 
192     /**
193      * This method has the same semantics as {@link ExecutorService#invokeAll(java.util.Collection)}
194      * but also includes the ability to be notified when each task's lifecycle changes.
195      *
196      * @param tasks the collection of tasks
197      * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
198      * @return A list of Futures representing the tasks, in the same
199      * sequential order as produced by the iterator for the given task
200      * list, each of which has completed.
201      * @throws InterruptedException if interrupted while waiting, in
202      * which case unfinished tasks are cancelled.
203      * @throws NullPointerException if tasks or any of its elements are <tt>null</tt>
204      * @throws RejectedExecutionException if any task cannot be scheduled
205      * for execution
206      */
207     <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks, ManagedTaskListener taskListener)
208         throws InterruptedException;
209 
210     /**
211      * This method has the same semantics as
212      * {@link ExecutorService#invokeAll(java.util.Collection, long, java.util.concurrent.TimeUnit)}
213      * but also includes the ability to be notified when each task's lifecycle changes.
214      *
215      * @param tasks the collection of tasks
216      * @param timeout the maximum time to wait
217      * @param unit the time unit of the timeout argument
218      * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
219      * @return A list of Futures representing the tasks, in the same
220      * sequential order as produced by the iterator for the given
221      * task list. If the operation did not time out, each task will
222      * have completed. If it did time out, some of these tasks will
223      * not have completed.
224      * @throws InterruptedException if interrupted while waiting, in
225      * which case unfinished tasks are cancelled.
226      * @throws NullPointerException if tasks, any of its elements, or
227      * unit are <tt>null</tt>
228      * @throws RejectedExecutionException if any task cannot be scheduled
229      * for execution
230      */
231     <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks,
232                                     long timeout, TimeUnit unit, ManagedTaskListener taskListener)
233         throws InterruptedException;
234 
235     /**
236      * This method has the same semantics as
237      * {@link ExecutorService#invokeAny(java.util.Collection)}
238      * but also includes the ability to be notified when each task's lifecycle changes.
239      *
240      * Executes the given tasks, returning the result
241      * of one that has completed successfully (i.e., without throwing
242      * an exception), if any do. Upon normal or exceptional return,
243      * tasks that have not completed are cancelled.
244      * The results of this method are undefined if the given
245      * collection is modified while this operation is in progress.
246      * @param tasks the collection of tasks
247      * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
248      * @return The result returned by one of the tasks.
249      * @throws InterruptedException if interrupted while waiting
250      * @throws NullPointerException if tasks or any of its elements
251      * are <tt>null</tt>
252      * @throws IllegalArgumentException if tasks empty
253      * @throws ExecutionException if no task successfully completes
254      * @throws RejectedExecutionException if tasks cannot be scheduled
255      * for execution
256      */
257     <T> T invokeAny(Collection<Callable<T>> tasks, ManagedTaskListener taskListener)
258         throws InterruptedException, ExecutionException;
259 
260     /**
261      * This method has the same semantics as
262      * {@link ExecutorService#invokeAny(java.util.Collection, long, java.util.concurrent.TimeUnit)}
263      * but also includes the ability to be notified when each task's lifecycle changes.
264      *
265      * @param tasks the collection of tasks
266      * @param timeout the maximum time to wait
267      * @param unit the time unit of the timeout argument
268      * @return The result returned by one of the tasks.
269      * @throws InterruptedException if interrupted while waiting
270      * @throws NullPointerException if tasks, any of its elements, or
271      * unit are <tt>null</tt>
272      * @throws TimeoutException if the given timeout elapses before
273      * any task successfully completes
274      * @throws ExecutionException if no task successfully completes
275      * @throws RejectedExecutionException if tasks cannot be scheduled
276      * for execution
277      */
278     <T> T invokeAny(Collection<Callable<T>> tasks,
279                     long timeout, TimeUnit unit, ManagedTaskListener taskListener)
280         throws InterruptedException, ExecutionException, TimeoutException;
281 
282 
283 }