Configuring managed executors
You can configure ManagedExecutorService
instances to run asynchronous
tasks with the specified thread context. The best practice is for Java™ EE applications to avoid directly managing their own threads; therefore, the
ManagedExecutorService
extends the JSE ExecutorService
to provide
a way to start asynchronous tasks within an application server environment. You might also configure
the ManagedExecutorService
to propagate various thread contexts that are relevant
to Java EE applications to the thread of the asynchronous
task.
About this task
ManagedExecutorService
is available under the
<concurrent-1.0>
feature and enabled in the server.xml
file as
follows:<featureManager>
<feature>concurrent-1.0</feature>
</featureManager>
Propagation of context to the thread of a task that is run by the
ManagedExecutorService
is managed by the context service. A default instance of the
context service (DefaultContextService
) is created by the server and configured to
propagate at least classloaderContext
, jeeMetadataContext
and
securityContext
. This default context service instance is used if a
ManagedExecutorService
is created without referring to a specific context service
instance or configuring a context service instance directly within. For more information about
context service instances, refer to the Configuring thread context service instances topic.
A default managed executor instance
(DefaultManagedExecutorService
) is available as
java:comp/DefaultManagedExecutorService
and uses the default context service
instance for thread context capture and propagation.
Concurrency policies configure concurrency-related behaviors
and constraints that apply to managed executors, such as maximum concurrency and maximum queue size.
By default, managed executors use a concurrencyPolicy
configuration element default
instance, defaultConcurrencyPolicy
, which has constraints that are unbounded. This
default concurrency policy is used if you configure a managed executor without referring to or
directly configuring a specific concurrencyPolicy
element as a nested element. If
multiple managed executors or other configuration elements refer to the same
concurrencyPolicy
element, the constraints in that policy apply across all of those
managed executor instances and other configured resources. You can also configure a managed executor
with a concurrency policy for long-running tasks, which applies to tasks with the
LONGRUNNING_HINT
execution property set to true
. The configuration
that is specified in the concurrencyPolicy
element and the long-running
concurrencyPolicy
element applies to tasks submitted to run as soon as possible.
The configuration does not apply to scheduled tasks.
Procedure
Example configuration in the server.xml
file:
Example
Managed executor service instances can be injected into application
components (by using @Resource
) or looked up with resource environment references
(resource-env-ref
). Regardless of how the instance is obtained, you can use it
interchangeably as javax.enterprise.concurrent.ManagedExecutorService
or its
java.util.concurrent.ExecutorSerivce
superclass.
- Example that looks up the default managed
executor:
ManagedExecutorService executor = (ManagedExecutorService) new InitialContext().lookup( "java:comp/DefaultManagedExecutorService"); executor.submit(doSomethingInParallel);
- Example that uses
@Resource
to inject asjava.util.concurrent.ExecutorService
:@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();
- Example that uses
@Resource
to inject asjavax.enterprise.concurrent.ManagedExecutorService
:@Resource(lookup="concurrent/execSvc1") ManagedExecutorService 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();
- Example
<resource-env-ref>
forjava.util.concurrent.ExecutorService
in theweb.xml
file:<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>
- Example lookup that uses a resource environment
reference:
ExecutorService execSvc2 = (ExecutorService) new InitialContext().lookup("java:comp/env/concurrent/execSvc2"); futures = execSvc2.invokeAll(Arrays.asList(task1, task2, task3));
- Example
<resource-env-ref>
forjavax.enterprise.concurrent.ManagedExecutorService
in theweb.xml
file:<resource-env-ref> <resource-env-ref-name>concurrent/execSvc2</resource-env-ref-name> <resource-env-ref-type>javax.enterprise.concurrent.ManagedExecutorService</resource-env-ref-type> </resource-env-ref>
- Example lookup that uses a resource environment reference and casts
to
ManagedExecutorService
:ManagedExecutorService execSvc2 = (ManagedExecutorService) new InitialContext().lookup("java:comp/env/concurrent/execSvc2"); futures = execSvc2.invokeAll(Arrays.asList(task1, task2, task3));