+

Search Tips   |   Advanced Search

Develop work objects to run code in parallel

We can run work objects in parallel, or in a different JEE (Java EE) context, by wrapping the code in a work object.

Your administrator must have configured at least one work manager using the administrative console.

To run code in parallel, wrap the code in a work object.

  1. Create a work object.

    A work object implements the com.ibm.websphere.asynchbeans.Work interface. For example, we can create a work object that dynamically subscribes to a topic and any component that has access to the event source can add an event on demand:

    class SampleWork implements Work
    {
     boolean released;
     Topic targetTopic;
     EventSource es;
     TopicConnectionFactory tcf;
    
     public SampleWork(TopicConnectionFactory tcf, EventSource es, Topic targetTopic)
     {
      released = false;
      this.targetTopic = targetTopic;
      this.es = es;
      this.tcf = tcf;
     }
    
     synchronized boolean getReleased()
     {
      return released;
     }
    
     public void run()
     {
      try
      {
       // setup our JMS stuff.
       TopicConnection tc = tcf.createConnection();
       TopicSession sess = tc.createSession(false, Session.AUTOACK);
       tc.start();
    
       MessageListener proxy = es.getEventTrigger(MessageListener.class, false);
       while(!getReleased())
       {
        // block for up to 5 seconds.
        Message msg = sess.receiveMessage(5000);
        if(msg != null)
        {
         // fire an event when we get a message
         proxy.onMessage(msg);
        }
       }
       tc.close();
      }
      catch (JMSException ex)
      {
       // handle the exception here 
       throw ex;
      }
      finally
      {
       if (tc != null)
       {
        try
        { 
         tc.close();
        }
        catch (JMSExceptin ex1) 
        {
         // handle exception
        }
       }
      }
     }
    
     // called when we want to stop the Work object.
     public synchronized void release()
     {
      released = true;
     }
    }
    
    As a result, any component that has access to the event source can add an event on demand, which allows components to subscribe to a topic in a more scalable way than by simply giving each client subscriber its own thread. The previous example is fully explored in the WebSphere Trader Sample. Refer to the Samples section of the Information Center for details.

  2. Determine the number of work managers needed by this application component.

  3. Look up the work manager or managers using the work manager resource reference (or logical name) in the java:comp namespace. (For more information on resource references, refer to the References topic.)
    InitialContext ic = new InitialContext();
    WorkManager wm = (WorkManager)ic.lookup("java:comp/env/wm/myWorkManager");
    The resource reference for the work manager (in this case, wm/myWorkManager) must be declared as a resource reference in the application deployment descriptor.

  4. Call the WorkManager.startWork() method using the work object as a parameter. For example:
    Work w = new MyWork(...);
    WorkItem wi = wm.startWork(w);
    The startWork() method can take a startTimeout parameter. This specifies a hard time limit for the Work object to be started. The startWork() method returns a work item object. This object is a handle that provides a link from the component to the now running work object.

  5. [Optional] If the application component needs to wait for one or more of its running work objects to complete, call the WorkManager.join() method. For example:
    WorkItem wiA = wm.start(workA);
    WorkItem wiB = wm.start(workB);
    ArrayList l = new ArrayList();
    l.add(wiA);
    l.add(wiB);
    if(wm.join(l, wm.JOIN_AND, 5000)) // block for up to 5 seconds
    {
    
    // both wiA and wiB finished
    }
    else
    {
    
    // timeout
    
    // we can check wiA.getStatus or wiB.getStatus to see which, if any, finished.
    }
    This method takes an array list of work items which your component wants to wait on and a flag that indicates whether the component will wait for one or all of the work objects to complete. You also can specify a timeout value.

  6. Use the release() method to signal the unit of work to stop running. The unit of work then attempts to stop running as soon as possible. Typically, this action is completed by toggling a flag using a thread-safe approach like the following example:
    public synchronized void release()
    {
     released = true;
    }
    The Work.run() method can periodically examine this variable to check whether the loop exits or not.


Related concepts

  • References in application deployment descriptor files


    Related tasks

  • Samples documentation