Work managers
A work manager provides threading for Java EE applications. Using the administrative console, an administrator can configure any number of work managers. Work manager properties include the Java EE context inheritance policy for tasks. The administrator binds each work manager to a unique place in JNDI. Use work manager objects in any one of the following interfaces:
- Managed executors
- javax.enterprise.concurrent.ManagedExecutorService
- javax.enterprise.concurrent.ManagedScheduledExecutorService
- java.util.concurrent.ExecutorService
- java.util.concurrent.ScheduledExecutorService
- Thread factories
- javax.enterprise.concurrent.ManagedThreadFactory
- java.util.concurrent.ThreadFactory
- Thread context service
- javax.enterprise.concurrent.ContextService
- Asynchronous beans
- com.ibm.websphere.asynchbeans.WorkManager
- CommonJ work manager
- commonj.work.WorkManager
The selected type of interface is resolved during the JNDI lookup time based on the value that we specify in the resource environment reference.
The work managers provide a programming model for the Java EE applications. For more information, see the Programming model section.
Avoid trouble: The javax.resource.spi.work.WorkManager class is a Java interface to be used by Java EE Connector Architecture (JCA) resource adapters. It is not an actual implementation of the WorkManager, which is used by Java EE applications.
When writing a web or EJB component that uses Concurrency Utilities for Java EE or asynchronous beans, the developer must include a resource environment reference in each component that needs access to a managed executor, thread factory, context service, or work manager. For more information on resource references, see the References topic. The component looks up a managed executor, thread factory, context service, or work manager that uses a logical name in the component, java: comp namespace, just as it looks up a data source, enterprise bean, or connection factory.
The deployer binds physical work managers to logical resource environment references (managed executors, thread factories, context services, or work managers) when the application is deployed.
For example, if a developer needs three thread pools to partition work between bronze, silver, and gold levels, the developer writes the component to pick a logical pool based on an attribute in the client application profile. The deployer has the flexibility to decide how to map this request for three thread pools. The deployer might decide to use a single thread pool on a small system. In this case, the deployer binds all three resource references to the same work manager instance (that is, the same JNDI name). A larger system might support three thread pools, so the deployer binds each resource reference to a different work manager. Work managers can be shared between multiple Java EE applications installed on the same server.
An application developer can use as many logical resource environments references as necessary. The deployer chooses whether to map one physical work manager or several to the logical managed executor, thread factory, context service, or work manager defined in the application.
All Java EE components that need to share asynchronous scope objects must use the same work manager. These scope objects have an affinity with a single work manager. An application that uses asynchronous scopes must verify that all of the components that use scope objects also use the same work manager.
When multiple work managers are defined, the underlying thread pools are created in a Java virtual machine (JVM) only if an application within that JVM looks up the work manager. For example, with 10 thread pools (work managers) defined, none are created until an application looks up these pools.
Important: Work managers do not support submitting work to remote JVMs.
CommonJ Work Manager
The CommonJ work manager contains a subset of the asynchronous beans work manager methods. Although CommonJ work manager functions in a Java EE environment, the interface does not return a new instance for each JNDI naming lookup, since this specification is not included in the Java EE specification.
The CommonJ Work specification optional feature for work running remotely is not supported. Even if a unit of work implements the java.io.Serializable interface, the unit of work does not run remotely.
How to look up a managed executor
An application can look up a managed executor as follows. Here, the component contains a resource environment reference named concurrent/myExecutor, which was bound to a physical work manager when the component was deployed:
InitialContext ic = new InitialContext(); ManagedExecutorService executor = (ManagedExecutorService) ic.lookup("java:comp/env/concurrent/myExecutor");
Inheritance Java EE contexts
Tasks that are submitted to managed executors and work managers can inherit the following Java EE contexts from the submitting thread. Contextual proxies can inherit these types of contexts from the thread that invokes the context service to create the contextual proxy. Managed thread factory threads can inherit these types of contexts from the thread that looks up or injects the managed thread factory.
- Internationalization context
- When this option is selected and the internationalization service is enabled, and the internationalization context that exists on the scheduling thread is available on the target thread.
- Work areas
- When this option is selected, the work area context for every work area partition that exists on the scheduling thread is available on the target thread.
- Application profile (deprecated)
- Application profile context is not supported and not available for most applications. For Java EE 1.3 applications, when this option is selected, the application profile service is enabled, and the application profile service property, 5.x compatibility mode, is selected. The application profile task associated with the scheduling thread is available on the target thread for Java EE 1.3 applications. For Java EE 1.4 or higher applications, the application profile task is a property of its associated unit of work, rather than a thread. This option has no effect on the behavior of the task in Java EE 1.4 or higher applications. The scheduled work that runs in a Java EE 1.4 application does not receive the profiling task of the scheduling thread.
- Security
- The task can be run as anonymous or as the client authenticated on the thread that created and submitted it. This behavior is useful because the task can do only what the caller can do. This action is more useful than a RUN_AS mechanism, for example, which prevents this kind of behavior. When we select the Security option, the JAAS subject that exists on the scheduling thread is available on the target thread. If not selected, the thread runs anonymously.
- Component metadata
- Component metadata is relevant only when the task is a simple Java object. If the task is a Java EE component, such as an enterprise bean, the component metadata is active.
The contexts that can be inherited depend on the work manager, which is used by the application that creates and submits the task. Using the administrative console, the administrator defines the sticky context policy of a work manager by selecting the services on which the work manager is to be made available.
Programming model
Work managers support the following programming models.
- Concurrency Utilities for Java EE. The Java EE specification standardizes this programming model, which includes Managed Executors, Managed Scheduled Executors and Managed Thread Factories, which inherit from the familiar Java SE java.util.concurrent API. It also includes the Context Service, which has no equivalent in the java.util.concurrent API.
- Asynchronous beans. The current asynchronous beans Work Manager, Event Source, asynchronous scopes, subsystem monitors, and Java EE Context interfaces are a part of the Asynchronous beans programming model.
- CommonJ Specification. The CommonJ programming model uses the WorkManager and TimerManager to manage threads and timers asynchronously in the Java EE environment.
For more information on managed executors, thread factories, context service, and work manager APIs, see the Javadoc.
Concurrency examples
Look up managed executor or work manager
Managed Executor Asynchronous beans CommonJ InitialContext ctx = new InitialContext();
ManagedExecutorService executor = (ManagedExecutorService)
ctx.lookup("java:comp/env/wm/myWorkMgr");InitialContext ctx = new InitialContext();
com.ibm.websphere.asynchbeans.WorkManager wm = (com.ibm.websphere.asynchbeans.WorkManager)
ctx.lookup("java:comp/env/wm/MyWorkMgr");InitialContext ctx = new InitialContext();
commonj.work.WorkManager wm = (commonj.work.WorkManager)
ctx.lookup("java:comp/env/wm/MyWorkMgr");Create your task
Managed Executor Asynchronous beans CommonJ public class MyWork implements Callable<Integer> { public Integer call() { System.out.println("Running....."); return 1; } } public class MyWork implements com.ibm.websphere.asynchbeans.Work { public void release() { ...... } public void run() { System.out.println("Running....."); } public class MyWork implements commonj.work.Work{ public boolean isDaemon() { return false; } public void release () { ..... } public void run () { System.out.println("Running....."); }Submit the task
Managed Executor Asynchronous beans CommonJ MyWork work1 = new MyWork(); yWork work2 = new MyWork(); // case 1: block until all items are done Collection<MyWork> tasks = Arrays.asList(work1, work2); List<Future<Integer>> futures = executor.invokeAll(tasks); for (Future<Integer> future : futures) System.out.println("work data=" + future.get()); //case 2: wait up to 1000 milliseconds for any of the items to complete. Integer result = executor.invokeAny( tasks, 1, TimeUnit.SECONDS); System.out.println("work data=" + result); MyWork work1 = new MyWork(); yWork work2 = new MyWork(); WorkItem item1; WorkItem item2; Item1=wm.startWork(work1); Item2=wm.startWork(work2); // case 1: block until all items are done ArrayList col1 = new ArrayList(); Col1.add(item1); Col1.add(item2); wm.join(col1, WorkManager.JOIN_AND, WorkManager.INDEFINITE); // when the works are done System.out.println("work1 data="+work1.getData()); System.out.println("work2 data="+work2.getData()); // we should complete case 1 before case 2 // case 2: wait up to 1000 milliseconds for any of the items to complete. Boolean ret = wm.join(col1, WorkManager.JOIN_OR, 1000); MyWork work1 = new MyWork(); yWork work2 = new MyWork(); WorkItem item1; WorkItem item2; Item1=wm.schedule(work1 ); Item2=wm.schedule(work2); // case 1: block until all items are done Collection col1 = new ArrayList(); col1.add(item1); col1.add(item2); wm.waitForAll(col1, WorkManager.INDEFINITE); // when the works are done System.out.println("work1 data="+work1.getData()); System.out.println("work2 data="+work2.getData()); // we should complete case 1 before case 2 // case 2: wait up to 1000 milliseconds for any of the items to complete. Collection finished = wm.waitForAny(col1,1000); // Check the workItems status if (finished != null) { Iterator I = finished.iterator(); if (i.hasNext()) { WorkItem wi = (WorkItem) i.next(); if (wi.equals(item1)) { System.out.println("work1 = "+ work1.getData()); } else if (wi.equals(item2)) { System.out.println("work1 = "+ work1.getData()); } } }
Create a managed scheduled executor, alarm manager, or timer manager
Managed Scheduled Executor Asynchronous beans CommonJ InitialContext ctx = new InitialContext(); ManagedScheduledExecutorService executor = (ManagedScheduledExecutorService) ctx.lookup("java:comp/env/wm/MyWorkMgr"); InitialContext ctx = new InitialContext(); com.ibm.websphere.asynchbeans.WorkManager wm = (com.ibm.websphere.asynchbeans.WorkManager) ctx.lookup("java:comp/env/wm/MyWorkMgr"); AsynchScope ascope; Try { Ascope = wm.createAsynchScope("ABScope"); } Catch (DuplicateKeyException ex) { Ascope = wm.findAsynchScope("ABScope"); ex.printStackTrace(); } // Get an AlarmManager AlarmManager aMgr= ascope.getAlarmManager(); InitialContext ctx = new InitialContext(); Commonj.timers.TimerManager tm = (commonj.timers.TimerManager) ctx.lookup("java:comp/env/tm/MyTimerManager");
Schedule a task, alarm, or timer.
Managed Scheduled Executor Asynchronous beans CommonJ // create task Runnable task = new StockQuoteTask( "qqq", "johndoe@example.com"); ScheduledFuture<?> future = executor.schedule(task, 1, TimeUnit.MINUTES); // Fixed-delay: schedule task to run // 1 minute from now and repeat every // hour thereafter. ScheduledFuture<?> future = executor.scheduleWithFixedDelay( task, 1, 60, TimeUnit.MINUTES); // Fixed-rate: schedule timer to expire // 1 minute from now and repeat every // hour thereafter ScheduledFuture<?> future = executor.scheduleAtFixedRate( task, 1, 60, TimeUnit.MINUTES); // create alarm ABAlarmListener listener = new ABAlarmListener(); Alarm am = aMgr.create(listener, "SomeContext", 1000*60); // create timer TimerListener listener = new StockQuoteTimerListener("qqq", "johndoe@example.com"); Timer timer = tm.schedule(listener, 1000*60); // Fixed-delay: schedule timer to expire in // 60 seconds from now and repeat every // hour thereafter. Timer timer = tm.schedule(listener, 1000*60, 1000*30); // Fixed-rate: schedule timer to expire in // 60 seconds from now and repeat every // hour thereafter Timer timer = tm.scheduleAtFixedRate(listener, 1000*60, 1000*30);
Related:
References in application deployment descriptor files Asynchronous beans Configure work managers