Configure managed scheduled executors
We can configure ManagedScheduledExecutorService instances to schedule asynchronous tasks to run with the thread context of the thread from which the task is scheduled. It is a best practice for Java EE applications to avoid directly managing their own threads; therefore, the ManagedScheduledExecutorService extends the JSE ExecutorService to provide a way to schedule asynchronous tasks within an application server environment. We might also configure the ManagedScheduledExecutorService to capture a thread context that is relevant to Java EE applications and propagate it to the thread of the scheduled task.
Important: In Liberty, managed scheduled executors do not have their own thread pools. Tasks submitted to managed scheduled executorinstances run on the common Liberty executorthread pool.
The managed scheduled executor<concurrent-1.0> feature is enabled in the server.xml file as follows:
<featureManager> <feature>concurrent-1.0</feature> </featureManager>
Thread context capture and propagation 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 ManagedScheduledExecutorService 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 Configure thread context service instances topic.
A default managed scheduled executorinstance (DefaultManagedScheduledExecutorService) is available as java:comp/DefaultManagedScheduledExecutorService 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 scheduled executors, such as maximum concurrency and maximum queue size. By default, managed scheduled 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 scheduled executorwithout referring to or directly configuring a specific concurrencyPolicy element as a nested element. If multiple managed scheduled executors or other configuration elements refer to the same concurrencyPolicy element, the constraints in that policy apply across all of those managed scheduled executor instances and other configured resources. We can also configure a managed scheduled executorwith a concurrency policy for long-running tasks, which applies to tasks with the LONGRUNNING_HINT execution property set to true. The configuration 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.
Example configuration in the server.xml file:
- Managed scheduled executorthat is registered in JNDI with the name
concurrent/scheduledExecutor, and that uses the default context service
instance:
<managedScheduledExecutorService jndiName="concurrent/scheduledExecutor"/>
<managedScheduledExecutorService jndiName="concurrent/scheduledExecutor1"> <contextService> <classloaderContext/> </contextService> <concurrencyPolicy max="5"/> </managedScheduledExecutorService>
<managedScheduledExecutorService jndiName="concurrent/scheduledExecutor2"> <contextService> <jeeMetadataContext/> <securityContext/> </contextService> </managedScheduledExecutorService>
<contextService id="contextSvc1"> <jeeMetadataContext/> </contextService> <managedScheduledExecutorService jndiName="concurrent/scheduledExecutor3" contextServiceRef="contextSvc1"/> <concurrencyPolicy id="normal" max="4" maxQueueSize="20"/> <concurrencyPolicy id="longRunning" max="2"/> <managedScheduledExecutorService jndiName="concurrent/scheduledExecutor3" contextServiceRef="contextSvc1" concurrencyPolicyRef="normal"/> <managedScheduledExecutorService jndiName="concurrent/scheduledExecutor4" contextServiceRef="contextSvc1" concurrencyPolicyRef="normal" longRunningPolicyRef="longRunning"/>
Example
Inject managed scheduled executors into application components (using @Resource) or look up with resource environment references (resource-env-ref). Regardless of how the instance is obtained, it can be used interchangeably as javax.enterprise.concurrent.ManagedScheduledExecutorService or any of the following superclasses: java.util.concurrent.ScheduledExecutorSerivce, java.util.concurrent.ExecutorService, javax.enterprise.concurrent.ManagedExecutorService
- Example that looks up the default managed scheduled
executor:
ManagedScheduledExecutorService executor= (ManagedScheduledExecutorService) new InitialContext().lookup( "java:comp/DefaultManagedScheduledExecutorService"); executor.schedule(beginSalePrices, 12, TimeUnit.HOURS); executor.schedule(restoreNormalPrices, 60, TimeUnit.HOURS);
@Resource(lookup="concurrent/scheduledExecutor2") ScheduledExecutorService executor; ... // schedule a task to run every half hour from now Runnable updateSalesReport = new Runnable() { public void run() throws Exception { // java:comp lookup is possible because <jeeMetadataContext> is configured DataSource ds = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/ds1"); ... query and update various database tables } }; ScheduledFuture<?> future = executor.scheduleAtFixedRate(updateSalesReport, 0, 30, TimeUnit.MINUTES);
@Resource(lookup="concurrent/scheduledExecutor2") ManagedScheduledExecutorService executor; ... usage is same as previous example
<resource-env-ref> <resource-env-ref-name>concurrent/scheduledExecutor1</resource-env-ref-name> <resource-env-ref-type>java.util.concurrent.ScheduledExecutorService</resource-env-ref-type> </resource-env-ref>
<resource-env-ref> <resource-env-ref-name>concurrent/scheduledExecutor2</resource-env-ref-name> <resource-env-ref-type>javax.enterprise.concurrent.ManagedScheduledExecutorService</resource-env-ref-type> </resource-env-ref>
ManagedScheduledExecutorService executor= (ManagedScheduledExecutorService) new InitialContext().lookup("java:comp/env/concurrent/scheduledExecutor2"); executor.schedule(payrollTask, fridaysAtMidnightTrigger);