001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package javax.util.concurrent;
018
019 import java.util.Collection;
020 import java.util.List;
021 import java.util.concurrent.Callable;
022 import java.util.concurrent.ExecutionException;
023 import java.util.concurrent.ExecutorService;
024 import java.util.concurrent.Future;
025 import java.util.concurrent.RejectedExecutionException;
026 import java.util.concurrent.TimeUnit;
027 import java.util.concurrent.TimeoutException;
028
029
030
031 /**
032 * A manageable version of a {@link java.util.concurrent.ExecutorService}.<p>
033 *
034 * A ManagedExecutorService provides methods for submitting tasks for execution
035 * in a managed environment. Implementations of the ManagedExecutorService are
036 * provided by a Java™ EE Product Provider. Application Component Providers
037 * use the Java Naming and Directory Interface™ (JNDI) to look-up instances of one
038 * or more ManagedExecutorService objects using resource environment references.<p>
039 *
040 * The Concurrency Utilities for Java™ EE specification describes several
041 * behaviors that a ManagedExecutorService can implement. The Application
042 * Component Provider and Deployer identify these requirements and map the
043 * resource environment reference appropriately.<p>
044 *
045 * The most common uses for a ManagedExecutorService is to run short-duration asynchronous
046 * tasks in the local JVM from a container such as an Enterprise
047 * JavaBean™ (EJB™) or servlet. Use a managed ThreadFactory for long-running
048 * daemon tasks.<p>
049 *
050 * Tasks run within the application component context that either
051 * submitted the task or created the ManagedExecutorService instance (server-managed or component-managed).
052 * All tasks run without an explicit transaction (they do not enlist in the application
053 * component's transaction). If a transaction is required, use a
054 * {@link javax.transaction.UserTransaction} instance. A UserTransaction instance is
055 * available in JNDI using the name: "java:comp/UserTransaction"<p>
056 *
057 * Example:<pre>
058 * public run() {
059 * // Begin of task
060 * InitialContext ctx = new InitialContext();
061 * UserTransaction ut = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
062 * ut.begin();
063 *
064 * // Perform transactional business logic
065 *
066 * ut.commit();
067 * }</PRE>
068 *
069 * Asynchronous tasks are typically submitted to the ManagedExecutorService using one
070 * of the <code>submit</code> methods, each of which return a {@link java.util.concurrent.Future}
071 * instance. The <code>Future</code> represents the result of the task and can also be used to
072 * check if the task is complete or wait for its completion.<p>
073 *
074 * If the task is cancelled, the result fo the task is a
075 * {@link java.util.concurrent.CancellationException} exception. If the task is unable
076 * to run due to start due to a reason other than cancellation, the result is a
077 * {@link javax.util.concurrent.AbortedException} exception.<p>
078 *
079 * Example:<pre>
080 * /**
081 * * Retrieve all accounts from several account databases in parallel.
082 * * Resource Mappings:
083 * * type: javax.util.concurrent.ManagedExecutorService
084 * * jndi-name: mes/ThreadPool
085 * * attributes:
086 * * Run Location = Local
087 * */
088 * public List<Account> getAccounts(long accountId) {
089 * try {
090 * javax.naming.InitialContext ctx = new InitialContext();
091 * <b>ManagedExecutorService mes = (ManagedExecutorService)
092 * ctx.lookup("java:comp/env/concurrent/ThreadPool");</b>
093 *
094 * // Create a set of tasks to perform the account retrieval.
095 * ArrayList<Callable<Account>> retrieverTasks = new ArrayList<Callable<Account>>();
096 * retrieverTasks.add(new EISAccountRetriever());
097 * retrieverTasks.add(new RDBAccountRetriever());
098 *
099 * // 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 }