Resource Thread Management

Resources using threads will want to use JCA's work management API. The work management API lets Resin manage threads for the resource rather than forcing the resource to manage its own threads. Since Resin is in a better position to manager threads, using the Work API is not only a convenience, but is a cleaner and more reliable implementation.

Demo

Files in this tutorial

WEB-INF/web.xmlConfigures the WorkResource
WEB-INF/classes/example/WorkResource.javaThe resource implementation launches the Work task and provides common state.
WEB-INF/classes/example/WorkTask.javaThe work task sleeps and counts.
index.jspThe starting page for the tutorial

The Work task

A Work task implements the javax.resource.work.Work interface. Like the familiar Runnable interface, Work has a public run() method as the main thread method. Work adds a release() method which allows Resin to notify the task when the resource should shut down.

The example task increments a counter and sleeps. The run method has the main loop.

The only complexity in the task implements the release() capability. The _isActive flag indicates whether the server is still alive. It is important that _isActive is set before the work task is submitted to avoid timing issues. In other words, it would be a mistake to set _isActive = true in the run() method since Resin could call release() before the run thread started.

The task uses wait(long) for sleeping. The release() will wake the task to let it shut down. In a work task, the main blocking calls should have timeouts or will be interruptable. A real application like a chat server might be reading a socket or waiting for a new connection. Those calls need timeouts so the task can shut down the service at the appropriate time.

WorkTask.java
import javax.resource.Work;

public class WorkTask implements Work {
  private volatile boolean _isActive = true;
  private int _count;

  int getCount()
  {
    return _count;
  }

  public void run()
  {
    while (_isActive) {
      _count++;

      try {
        synchronized (this) {
          wait(10000);
        }
      } catch (Throwable e) {
      }
    }
  }

  public void release()
  {
    _isActive = false;

    try {
      synchronized (this) {
        notifyAll();
      }
    } catch (Throwable e) {
    }
  }

The Resource

The WorkResource in this example is simple since it only needs to launch the work task. As with the previous examples, the resource extends com.caucho.jca.AbstractResourceAdapter to simplify the example.

WorkResource.java

import com.caucho.jca.AbstractResourceAdapter;

public class WorkResource extends AbstractResourceAdapter {
  public void start(BootstrapContext ctx)
    throws ResourceAdapterInternalException
  {
    WorkTask work = new WorkTask();

    WorkManager workManager = ctx.getWorkManager();
    
    try {
      // Submits the work, but does not wait for the result.
      // In other words, it spawns a new thread
      workManager.startWork(work);
    } catch (WorkException e) {
      throw new ResourceAdapterInternalException(e);
    }
  }

  public String toString()
  {
    return "WorkResource[" + _workTask.getCount() + "]";
  }
}

Demo


Copyright © 1998-2006 Caucho Technology, Inc. All rights reserved.
Resin ® is a registered trademark, and Quercustm, Ambertm, and Hessiantm are trademarks of Caucho Technology.