![[8.5.5.4 or later]](../ng_v8554.gif)
Configuring managed thread factories
You 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. You might also configure the ManagedThreadFactory to capture a thread context that is relevant to Java EE applications and propagate it to the new thread.
About this task
<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 does not specify a context service. 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.
Procedure
Example configuration in the server.xml file:
Example
Managed thread factories 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, it can be used interchangeably as javax.enterprise.concurrent.ManagedThreadFactory or java.util.concurrent.ThreadFactory.
- Example that looks up the default managed thread
factory:
ManagedThreadFactory threadFactory = (ManagedThreadFactory) new InitialContext().lookup( "java:comp/DefaultManagedThreadFactory"); // Create an executor that always runs tasks with the thread context of the managed thread factory ExecutorService executor = new ThreadPoolExecutor( coreThreads, maxThreads, keepAliveTime, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(workRequestQueueSize), threadFactory, new ThreadPoolExecutor.AbortPolicy());
- Example that uses @Resource to inject asjava.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