You can configure application server managed ExecutorService instances to run asynchronous tasks with the specified context. It is a best practice for Java™ EE applications to avoid directly managing their own threads; therefore, the managed ExecutorService extends the JSE Executor to provide a way to execute asynchronous tasks within an application server environment. You might also configure the managed Executor Service to propagate various contexts that are relevant to Java EE applications to the thread of the asynchronous task.
<featureManager>
<feature>concurrent-1.0</feature>
</featureManager>
Example configuration in the server.xml file:
Managed executor serviced instances can be injected into application components (by using @Resource) or looked up with resource environment references (resource-env-ref):
@Resource(lookup="concurrent/execSvc1")
ExecutorService execSvc1;
...
// submit task to run
Future<Integer> future1 = execSvc1.submit(new Callable<Integer>() {
public Integer call() throws Exception {
// java:comp lookup is possible because <jeeMetadataContext> is configured
DataSource ds = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/ds1");
... make updates to the database
return updateCount;
}
});
Future<Integer> future2 = execSvc1.submit(anotherTaskThatUpdatesADatabase);
numUpdatesCompleted = future1.get() + future2.get();
<resource-env-ref>
<resource-env-ref-name>concurrent/execSvc2</resource-env-ref-name>
<resource-env-ref-type>java.util.concurrent.ExecutorService</resource-env-ref-type>
</resource-env-ref>
ExecutorService execSvc2 =
(ExecutorService) new InitialContext().lookup("java:comp/env/concurrent/execSvc2");
futures = execSvc2.invokeAll(Arrays.asList(task1, task2, task3));