+

Search Tips   |   Advanced Search

Work managers

A work manager is a thread pool created for JEE applications that use asynchronous beans.

Using the administrative console, an administrator can configure any number of work managers. The administrator specifies the properties of the work manager, including the Java EE context inheritance policy for any asynchronous beans that use the work manager. The administrator binds each work manager to a unique place in JNDI. Use work manager objects in any one of the following interfaces:

The selected type of interface is resolved during the JNDI lookup time. The interface type is the value specified in the ResourceRef, rather than the interface type specified in the configuration object. For example, we can have one ResourceRef for each interface per configuration object, and each ResourceRef lookup returns that appropriate type of instance.

The work managers provide a programming model for the Java EE 1.4 applications. For more information, see the Programming model section in this article.

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. gotcha

When writing a Web or EJB component that uses asynchronous beans, the developer should include a resource reference in each component that needs access to a work manager. For more information on resource references, refer to the References topic. The component looks up a work manager using 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 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 machine. In this case, the deployer binds all three resource references to the same work manager instance (that is, the same JNDI name). A larger machine 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 work managers as necessary. The deployer chooses whether to map one physical work manager or several to the logical 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 should verify that all of the components using scope objects 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, there might be ten thread pools (work managers) defined, but none are actually created until an application looks these pools up.

Important: Asynchronous beans do not support submitting work to remote JVMs.


CommonJ Work Manager

The CommonJ work manager is similar to the work manager. The difference between the two is that the CommonJ work manager contains a subset of the asynchronous beans work manager methods. Although CommonJ work manager functions in a Java EE 1.4 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.


Remote start of work. 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 work manager

An application can look up a work manager as follows. Here, the component contains a resource reference named wm/myWorkManager, which was bound to a physical work manager when the component was deployed:

InitialContext ic = new InitialContext();
WorkManager wm = (WorkManager)ic.lookup("java:comp/env/wm/myWorkManager");


Inheritance Java EE contexts

  • Asynchronous beans can inherit the following Java EE contexts.

    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 area

    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 Java EE 1.4 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 that is associated with the scheduling thread is available on the target thread for Java EE 1.3 applications. For Java EE 1.4 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 applications. The scheduled work that runs in a Java EE 1.4 application does not receive the application profiling task of the scheduling thread.

    Security

    The asynchronous bean can be run as anonymous or as the client authenticated on the thread that created it. This behavior is useful because the asynchronous bean 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 you 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 asynchronous bean is a simple Java object. If the bean 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 used by the application that creates the asynchronous bean. 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.

    • CommonJ Specification. The Application Server Version 6.0 CommonJ programming model uses the WorkManager and TimerManager to manage threads and timers asynchronously in the Java EE 1.4 environment.

    • Asynchronous beans and CommonJ specification extensions. The current asynchronous beans Event Source, asynchronous scopes, subsystem monitors and Java EE Context interfaces are a part of the CommonJ extension.

    The following table describes the method mapping between the CommonJ and Asynchronous beans APIs. We can change the current asynchronous beans interfaces to use the CommonJ interface, while maintaining the same functions.

    CommonJ package API Asynchronous beans package API
    Work manager
    Work manager
    Asynchronous beans Field - IMMEDIATE (long)
    Field - IMMEDIATE (int)

    Field - INDEFINITE
    Field - INDEFINITE

    schedule(Work) throws WorkException, IllegalArgumentException
    startWork(Work) throws WorkException, IllegalArgumentException

    schedule(Work, WorkListener) throws WorkException, IllegalArgumentException

    Important: Configure the work manager work timeout property to the value you previously specified as timeout_ms on startWork. The default timeout value is INDEFINITE.


    startWork(Work, timeout_ms, WorkListener) throws WorkException, IllegalArgumentException

    waitForAll(workItems, timeout_ms)
    join(workItems, JOIN_AND, timeout_ms)

    waitForAny(workItems, timeout_ms)
    join(workItems, JOIN_OR, timeout_ms)
    WorkItem
    WorkItem

    getResult
    getResult

    getStatus
    getStatus
    WorkListener
    WorkListener

    workAccepted(WorkEvent)
    workAccepted(WorkEvent)

    workCompleted(WorkEvent)
    workCompleted(WorkEvent)

    workRejected(WorkEvent)
    workRejected(WorkEvent)

    workStarted(WorkEvent)
    workStarted(WorkEvent)
    WorkEvent
    WorkEvent

    Field - WORK_ACCEPTED
    Field - WORK_ACCEPTED

    Field - WORK_COMPLETED
    Field - WORK_COMPLETED

    Field - WORK_REJECTED
    Field - WORK_REJECTED

    Field - WORK_STARTED
    Field - WORK_STARTED

    getException
    getException

    getType
    getType

    getWorkItem().getResult()

    Important: This API is valid only after the work is complete.


    getWork
    Work (extends Runnable) Work (Extends Runnable)

    isDaemon
    *

    release
    release
    RemoteWorkItem RemoteWorkItem capability is not provided by WebSphere Application Sever. Use Distributed WorkManager in the WebSphere Extended Deployment product. NA
    TimerManager
    AlarmManager

    resume
    *

    schedule(Listener, Date)
    create(Listener, context, time) ** need to convert the parameters

    schedule(Listener, Date, period)


    schedule(Listener, delay, period)


    scheduleAtFixedRate (Listener, Date, period)


    scheduleAtFixedRate (Listener, delay, period)


    stop


    suspend

    Timer
    Alarm

    cancel
    cancel

    getPeriod


    getTimerListener
    getAlarmListener

    scheduledExecutionTime

    TimerListener
    AlarmListener

    timerExpired(timer)
    fired(alarm)
    StopTimerListener
    Not applicable

    timerStop(timer)

    CancelTimerListener
    Not applicable

    timerCancel(timer)

    WorkException (Extends Exception) WorkException (Extends WsException)
    WorkCompletedException (Extends WorkException) WorkCompletedException (Extends WorkException)
    WorkRejectedException (Extends WorkException) WorkRejectedException (Extends WorkException)
    For more information on work manager APIs, refer to the Javadoc.


    Work manager examples

    Asynchronous beans CommonJ ExecutorService
    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");
    InitialContext ctx = new InitialContext();
    java.util.concurrent.ExecutorService execSvc = 
     (java.util.concurrent.ExecutorService
           ctx.lookup("java:comp/env/concurrent/execSvc");

    Asynchronous beans CommonJ ExecutorService
    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.....");
       }
    // A simple task that can be used as either Callable or Runnable
     public class MyWork implements Callable<Integer>, Runnable {
       final AtomicInteger counter;
       
       public MyWork(AtomicInteger counter) {
         this.counter = counter;
       }
       
       @Override 
       // the Callable implementation    
       public Integer call() {
         int i = counter.incrementAndGet();
         System.out.println("callable counter = " + i);
         return i;
       }
       
       @Override 
       // the Runnable implementation    
       public void run() {
         int i = counter.incrementAndGet();
         System.out.println("runnable counter = " + i);
       }
     }

    Asynchronous beans CommonJ ExecutorService
     MyWork work1 = new MyWork();
     MyWork 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());
     
     // you 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();
     MyWork 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());
     
     
     // 
    // you 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());
           }
       }
     }
    AtomicInteger counter = new AtomicInteger();
       
       Callable<Integer> callableTask = new MyWork(counter);
       Runnable runnableTask = new MyWork(counter);
       
       // Submit single tasks for execution
       Future<Integer> future1 = execSvc.submit(callableTask);
       Future<?> future2 = execSvc.submit(runnableTask);
       Future<Integer> future3 = execSvc.submit(runnableTask, 100);
       
       // in a perfect world the results should be:
       // future1.get() -> 1
       // future2.get() -> null
       // future3.get() -> 100
       
       List<Callable<Integer>> tasks = new ArrayList<Callable<Integer>>(3);
       tasks.add(new MyWork(counter));
       tasks.add(new MyWork(counter));
       tasks.add(new MyWork(counter));
       
       // submit multiple tasks and block until all items are done
       List<Future<Integer>> futures = execSvc.invokeAll(tasks);
       futures = execSvc.invokeAll(tasks, 1000, TimeUnit.MILLISECONDS); 
       // with timeout
       
       // submit multiple tasks and  block until 1 task completes successfully    
       Integer result = execSvc.invokeAny(tasks);
       result = execSvc.invokeAny(tasks, 1000, TimeUnit.MILLISECONDS); 
    // with timeout

    Asynchronous beans CommonJ
     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");

    CommonJ
     
    // 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 concepts

    References in application deployment descriptor files
  • Asynchronous beans
  • Configure work managers