Configure managed thread factories
We can configure ManagedThreadFactory instances to create new threads that run with a thread context of the thread from which the managed thread factory is looked up or injected. It is a best practice for Java EE applications to avoid directly managing their own threads; therefore, the ManagedThreadFactory extends the JSE ThreadFactory to provide a way to create managed threads within an application server environment. We might also configure the ManagedThreadFactory to capture a thread context that is relevant to Java EE applications and propagate it to the new thread.
The managed thread factory is available under the <concurrent-1.0> feature and enabled in server.xml 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 ManagedThreadFactory 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 instance of ManagedThreadFactory (DefaultManagedThreadFactory) is available as java:comp/DefaultManagedThreadFactory and uses the default context service instance for thread context capture and propagation.
Example configuration in server.xml:
- Managed thread factory that is registered in JNDI with the name concurrent/threadFactory, and that uses the default context service instance:
<managedThreadFactory jndiName="concurrent/threadFactory" maxPriority="5"/>
- Managed thread factory with context service configured to capture and propagate securityContext only:
<managedThreadFactory jndiName="concurrent/threadFactory1"> <contextService> <securityContext/> </contextService> </managedThreadFactory>
- Managed thread factory with classloaderContext and jeeMetadataContext:
<managedThreadFactory jndiName="concurrent/threadFactory2"> <contextService> <classloaderContext/> <jeeMetadataContext/> </contextService> </managedThreadFactory>
- Thread context service that is shared by multiple managed thread factories:
<contextService id="contextSvc1"> <jeeMetadataContext/> </contextService> <managedThreadFactory jndiName="concurrent/threadFactory3" contextServiceRef="contextSvc1"/> <managedThreadFactory jndiName="concurrent/threadFactory4" contextServiceRef="contextSvc1"/>
Example
Managed thread factories can be injected into application components (using @Resource) or looked up with resource environment references (resource-env-ref). Regardless of how the instance is obtained, it can be used interchangeably as javax.enterprise.concurrent.ManagedThreadFactory or java.util.concurrent.ThreadFactory.
- Example that uses @Resource to inject as java.util.concurrent.ThreadFactory: :
@Resource(lookup="concurrent/threadFactory2") ThreadFactory threadFactory ... // create a new thread Thread dailySalesAnalysisTask = threadFactory.newThread(new Runnable() { public void run() { // java:comp lookup is possible because <jeeMetadataContext> is configured DataSource ds = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/ds1"); ... analyze the data } }); dailySalesAnalysisTask.start();
- Example that uses @Resource to inject as javax.enterprise.concurrent.ManagedThreadFactory:
@Resource(lookup="concurrent/threadFactory2") ManagedThreadFactory threadFactory; ... usage is same as previous example
- Example <resource-env-ref> for java.util.concurrent.ThreadFactory in the web.xml file:
<resource-env-ref> <resource-env-ref-name>concurrent/threadFactory1</resource-env-ref-name> <resource-env-ref-type>java.util.concurrent.ThreadFactory</resource-env-ref-type> </resource-env-ref>
- Example <resource-env-ref> for javax.enterprise.concurrent.ManagedThreadFactory in the web.xml file:
<resource-env-ref> <resource-env-ref-name>concurrent/threadFactory2</resource-env-ref-name> <resource-env-ref-type>javax.enterprise.concurrent.ManagedThreadFactory</resource- env-ref-type> </resource-env-ref>
- Example lookup that uses a resource environment reference:
ManagedThreadFactory threadFactory = (ManagedThreadFactory) new InitialContext().lookup("java:comp/env/concurrent/threadFactory"); // Create a scheduled executor that always runs tasks with the thread context of the managed thread factory ScheduledExecutorService executor = Executors.newScheduledThreadPool(5, threadFactory); ... use executor to schedule tasks from any thread
Parent topic: Administer the Liberty profile manually