Thursday, September 29, 2011

How to show code in blog post

Web browsers are smart, you give them codes, they render them into images and display on the monitor. That’s good, but what if all you want to do is just to display the codes in your post, as it is. There are quite a few solutions available on the internet, but what I am going to show you is think among the better ones.

(Note: Before we proceed, if you plan to use this only occasionally, then just use tags. It’s built-in, so you don’t have to add anything, but the code won’t look as good).

It is called SyntaxHighlighter by Alex Gorbatchev. It uses JavaScript library, does the highlighting using CSS, and supports (the highlighting of) many programming languages. I am going to explain how do you go about using this tool:

1. Preparing your template

  1. Download the scripts. You can download all the required script files here.
  2. Extract the files and upload them to your server. Upload only the needed files, you’ll find out the one you need as you read along. If you don’t have a file host, don’t despair, there is a free hosted version.
  3. Link the files to your template by going to Design > Edit HTML and inserting the code below right before the tag:
    (For the purpose of this demonstration it will be assumed that scripts/*.* was extracted and put inside /scripts folder and styles/*.* are put inside /styles folder.)
    1<link type="text/css" rel="stylesheet" href="/styles/shCore.css" />
    2<link type="text/css" rel="stylesheet" href="/styles/shThemeDefault.css" />
    3<script type="text/javascript" src="/scripts/shCore.js">script>
    4<script type="text/javascript" src="/scripts/shBrushJScript.js">script>
    5<script type="text/javascript" src="/scripts/shBrushBash.js">script>
    6<script type="text/javascript" src="/scripts/shBrushCpp.js">script>
    7<script type="text/javascript">
    8SyntaxHighlighter.all();
    9script>
  4. You can apply a theme (as in code line 2) other than the default. Upload them and add the link into the code. For additional syntax support, add more brushes (as in code line 4 to 6). But remember more links equals slower page loading.

2. Adding code block (that you want to show) into your post

SyntaxHighlighter looks for

 (pre-formatted text) tags  which have specially formatted class attribute. The only required parameter is brush (see configuration) which should be set to one of the brush aliases that you have loaded previously.

  1. First you need to HTML-escape your code snippet to convert special characters to such as < and > to their escape form < and > respectively. You can do this manually or use an online escape tool.
  2. Go to post editor and switch to Edit HTML mode.
  3. Place the escaped code inside
     tags, with class attribute included, like so:      
    1<pre class="brush: js">
    2ENTER YOUR ESCAPED CODE SNIPPET HERE
    3pre>

If you use Window Live Writer to edit you posts, you can use this Syntax Highlighter plug-in by Arnold Matusz. With this plug-in, you just copy and paste the code into the plug-in screen. You don’t have to escape the code or manually enter it, all you have to do is paste the code inside the plugin window.

3. Integrating Syntax Highlighter with Blogger

If you are hosting on blogger.com, you must add this line:

1SyntaxHighlighter.config.bloggerMode = true

See the code I use in Blogger Sentral below.

One more thing, go to Dashboard > Settings > Formatting and set “Convert Line Breaks” to No.

4. Using free hosted version

I use this option, no need to download or upload anything. See my code below:

01
02<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
03<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
04<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>
05<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>
06<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'/>
07<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/>
08<script type='text/javascript'>
09SyntaxHighlighter.config.bloggerMode = true;
10SyntaxHighlighter.all();
11script>
12

The Work Manager API: Parallel Processing Within a J2EE Container

http://www.devx.com/java/Article/28815/1954

The Work Manager API offers a solution for performing parallel processing directly within a managed environment. You can leverage this new offering to implement parallel processing within a J2EE container.
Corporations encounter various scenarios in which they need parallel processing to achieve high throughput and better response times. For example, various financial institutions perform reconciliation as batch jobs at the end of each day. In these cases, a company may need to process millions of units of work to reconcile its portfolio. These units of work typically are processed in parallel. This article demonstrates how to accomplish parallel processing within a J2EE container.

The J2EE design revolves around the request/response paradigm. For a login request, a user typically provides a user name and password to the server and waits for a response to get access to the site. A J2EE container can serve multiple users at the same time (in parallel) by managing a pool of threads, but for various reasons opening independent threads within a single J2EE container is not recommended. Some containers' security managers will not allow user programs to open threads. Moreover, if some containers allowed opening threads, then they would not manage those threads and therefore no container-managed services would be available for the threads. That would leave you to implement these services manually, which is tedious and liable to add complexity to your code.

Until recently, performing parallel processing directly within a managed environment (J2EE container) was not advisable. Thankfully, IBM and BEA came up with a joint specification that resolves this problem. This JSR is named "JSR-237: Work Manager for Application Servers". JSR-237 specifies the Work Manager API, which provides abstraction from the lower-level APIs that enable an application to access a container-managed thread. Work Manager API also provides a mechanism to join various concurrent work items, so an application can programmatically add the dependency of work completion as a condition for starting other tasks. This can be useful for implementing workflow types of application. These features were difficult to implement prior to Work Manager.

This article discusses this specification and its design, and presents some code snippets for implementing a concurrent application for a managed environment. First, it discusses the design of the Work Manager API and it's key interfaces.

Work Manager Design

The Work Manager API defines Work as a unit of work, which you want to execute asynchronously. Work is an abstraction of the lower-level java.lang.Runnable interface. Implementation of the Work interface requires you to define a run() method and implement business logic for performing tasks/work in this method. The Work Manager API has six key interfaces for implementation:
  • WorkManager
  • Work
  • WorkListener
  • WorkItem
  • RemoteWorkItem
  • WorkEvent
Figure 1 shows a class diagram for these interfaces.

Click to enlarge
Figure 1: Work Manager Class Diagram

J2EE container providers such as BEA and IBM must implement the WorkManager interface, and server administrators can create WorkManager by defining it in their J2EE container configurations. Most leading J2EE containers provide user interface (UI) tools for defining WorkManager. WorkManager encapsulates a pool of threads. By invoking the schedule(Work work) method of the WorkManager interface, a client can schedule work for asynchronous execution. Behind the scenes, the Work Manager implementation gets a container-managed thread for executing the Work object. So work is executed in parallel with the current thread. A previously mentioned, the Work interface implements a run method of the java.lang.Runnable interface, so a thread can execute an object of type Work.




Work Lifecycle

Work has states in its lifecycle, as illustrated in Figure 2.

Click to enlarge
Figure 2: Work Lifecycle

A Work lifecycle starts after the schedule method of Work Manager is invocated. At any given time, Work can be in any one of the following states:

  • Accepted: Work Manager has accepted work for further processing.
  • Started: Work just started execution on a thread. You can assume this state just prior to entering the run method of Work.
  • Completed: Work just completed execution. You can assume this state to be just after exiting from run method.
  • Rejected: Work could be rejected at various stages. Work Manager can reject work in case it's unable to process a request.

Work Manager provides a listener interface (WorkListener) that defines four callback methods associated with the Work lifecycle:

  • workAccepted
  • workStarted
  • workCompleted
  • workRejected

Work Manager invokes these methods at corresponding states of the Work lifecycle. The user can implement the WorkListener interface and pass implementation of WorkListener to Work Manager while scheduling work. Work Manager would invoke callback methods corresponding to each state.

Remote Processing of Work

A Work Manager implementation can execute work in a local JVM or transport work for execution by a remote JVM. To process work on a remote JVM implementation, the Work interface needs to implement the java.io.Serializable interface. A Work Manager implementation can check whether Work has implemented the Serializable interface, and then send it to a remote JVM for execution. Processing work in a remote JVM is implementation specific, and some implementations can execute work locally even if Work has implemented Serializable. Work Manager's design encapsulates the complexities of sending work to remote JVMs from a client.

App server providers could implement a scalable Work Manager framework by implementing a work manager capable of executing work on remote JVMs.

Adding Dependency to Work Completion

Work Manager provides a simple mechanism for adding dependencies of work completion on to other tasks. Work Manager provides a simple API for the common join operation. The current specification provides two methods for accomplishing a simple join. Both take a collection of WorkItem objects to check the status of Work objects and a timeout parameter to timeout after a specified interval, even if the condition is not met:
  • waitForAll(): An application waits for all tasks to complete before moving on to further steps. This is a blocking call with configurable timeout value.
  • waitForAny(): An application waits for any one of the work items to complete before moving on to the next step.

Work Manager defines two constants that correspond to timeouts:

  • WorManager.INDEFINITE: Wait indefinitely for any/all work to complete (Use this option with care, because it could lead your application thread to wait forever.)
  • WorManager.IMMEDIATE: Check status of any/all work completion and return immediately




Configuring Work Manager for J2EE Container

J2EE container providers that support the Work Manager API normally provide a UI-based tool for defining Work Manager. WebLogic 9.0, for example, provides such a tool for configuring Work Manager (Figure 3 shows a WebLogic 9.0 administrative console showing a Work Manager configuration). The user needs to provide a work manager name and point Work Manager to a target server or cluster. As an example, I have created TestWorkManager.

Click to enlarge
Figure 3: WebLogic Administrative Console Showing TestWorkManager

An implementation also can provide features that are not part of a specification. For example, WebLogic allows users to configure Work Manager with the following optional parameters:

  • Minimum thread constraint: The minimum number of threads allocated to resolve deadlock
  • Maximum thread constraint: The maximum number of threads that can be allocated to execute requests
  • Capacity constraint: Total number of requests that can queue or execute before WebLogic starts rejecting requests

Implementation of Work Manager-Based Application

Take the following steps to implement an application for parallel processing with WebLogic 9.0:
  1. Implement the Work interface and define your business logic in the run() method. The current version of WebLogic 9.0 does not support execution of work in remote JVMs, but it may in the future. So it's a good practice to implement java.io.Serializable as well for future enhancements to Work Manager.
  2. Implement the WorkListener interface for listening to work lifecycle events. Although not necessary, this step is a good practice.
  3. JNDI lookup is the primary way of accessing Work Manager. Servlets and EJB can access Work Manager via JNDI lookup within the local JVM. You can associate the Work Manager resource to an application by defining resource-ref in the appropriate deployment descriptor. For a servlet to access Work Manager, you define the resource-ref in web.xml. For EJB, you can define the resource-ref in ejb-jar.xml:
     
  4. Now, look at a code snippet that invokes Work Manager and schedules work for execution on a container-managed thread. The following snippet shows the code for using the Work Manager API:
//#1. Get Work Manager from local JNDI
WorkManager workManager;
InitialContext ctx = new InitialContext();
this.workManager = (WorkManager)ctx.lookup("java:comp/env/wm/TestWorkManager");
 
//#2. Create instance of Work and WorkListener implementation
Work work = new WorkImpl("HelloWorld");
WorkListener workListener=new WorkListenerImpl();
 
//#3. Schedule work for execution, which would start in parallel to current thread
WorkItem workItem = workManager.schedule(work, workListener);
 
//#4. Create list of WorkItem you want to wait for completion
List workItemList=new ArrayList();
workItemList.add(workItem);
 
//#5. Wait for completion of work
this.workManager.waitForAll(workItemList, WorkManager.INDEFINITE);
 
//#6. You can get results from Work implementation
WorkImpl workImpl= (WorkImpl)workItem.getResult();

In this implementation, you assume WorkImpl and WorkListenerImpl are
implementations of the Work and WorkListener interfaces.

The Takeaway

This article discussed a simple and powerful API for parallel execution of tasks within a managed environment. It explained the high-level design of the Work Manager API and explored WebLogic 9.0's working implementation of the Work Manager API.

With the Work Manager API, developers can design robust applications for executing tasks in parallel, listen to work lifecycle events, and add the dependency of task completion to other tasks. Work Manager implementations also could be highly scalable if app server providers implemented a work manager capable of executing work on remote JVMs.


WebSphere WorkManager and Java Thread Pool

Summary: Asynchronous beans provide an efficient and safe global thread pool that can be used by multiple applications. When you require the use of specialized thread pools, you can construct a thread factory using the Asynchronous Beans EventSource interface with IBM® WebSphere® Application Server V5.x or V6.x, and achieve the freedom of using whatever advanced thread usage patterns are necessary without sacrificing performance.

Introduction

IBM WebSphere Application Server software provides two mechanisms that enable J2EE™ application developers to use threads safely in servlets and EJB components:

  • Asynchronous beans
  • Commonj Timer and WorkManager for Application Servers 1.1 specification.

Both programming models let you create pooled and daemon threads to run J2EE business logic.

In both programming models, threads can be reused by different applications. This is achieved by applying and removing the J2EE context information on and off the thread when the application logic begins and ends. A single thread pool can therefore be used by multiple applications. The identity of the thread will change each time it is used.

The context of the thread must be changed each time the thread is reused, which can cause a significant overhead to applications that may be doing very little activity on those threads. In these cases, it is desirable to have a component-scoped thread pool, with a fixed J2EE context on each thread. This can be accomplished using the Asynchronous Beans EventSource interface.

This article describes how a thread factory can be constructed using an Asynchronous Beans EventSource, and includes a downloadable sample, called the Concurrent Adapter, which can be used with third-party thread pool implementations to create fast thread pools that will work on WebSphere Application Servers.

Global thread pooling

WebSphere Application Server ships a high-performance and highly-scalable thread pool implementation. The WorkManagers from asynchronous beans and Commonj both use this thread pool for all pooled threads.

Since the WorkManager instances are available in the global namespace, they can be shared amongst multiple applications and, therefore, require J2EE context switching. To achieve this, the WorkManager takes a snapshot of the J2EE context on the thread when the work is submitted. The resulting object becomes a WorkWithExecutionContext (WWEC) object (Figure 1).


Figure 1. WorkWithExecutionContext
Figure 1. WorkWithExecutionContext

When using the WorkManager as a global thread pool (Figure 2), each work submitted to the thread pool will have the application's context applied and removed from the thread each time the work is allocated to a thread:

  1. Work is submitted to the WorkManager thread pool (the blue box)

    1. A snapshot is taken of the J2EE application context and stored with the work as a WWEC object.
    2. The WWEC is added to the pool's input queue.
  2. A worker thread pulls the next WWEC from the input queue and runs it.

    1. A snapshot is taken of the current J2EE application context on the worker thread to restore later after the work completes.
    2. The J2EE context stored with the WWEC is applied to the thread.
    3. The work is run.
    4. The J2EE context is removed from the thread and the previous context is reapplied.
  3. The worker thread now waits for more work to appear on the input queue.


Figure 2. Global thread pool sharing with a WorkManager
Figure 2. Global thread pool sharing with a WorkManager

Component-scoped thread pooling

If a thread pool is only going to be used by a single application or component (a servlet or EJB) and the work to be submitted can tolerate a single, common J2EE context identity, then using a custom thread pool with a thread factory can significantly increase performance. This is a component-scoped thread pool.

Component-scoped thread pool threads will all share the J2EE context of the application component that created it. If created, for example, by a startup bean, each thread will contain the context of the startup bean's start() method, and each thread will behave as if it were running within the scope of that startup bean. The startup bean is therefore the owner of the thread pool instance. All business logic will run with the java:comp namespace and security context of the startup bean's start() method, regardless of the servlet or EJB that submits the work.

All threads in a component-scoped thread pool are asynchronous bean daemon threads and have the same lifecycle of the application that created it. If the application ends, the release() method of each daemon Work thread in the pool will be called.

When using custom component-scoped thread pools (Figure 3), each worker thread in the pool is initialized with a daemon thread created by the WorkManager. The WorkManager becomes a thread factory. Each thread will share the same J2EE context of the pool creator:

  1. A Runnable is submitted to a custom thread pool.

  2. A thread pool worker thread pulls the next WWEC from the input queue and runs it. Each worker thread has the J2EE context of the thread pool creator component applied to it.

    1. The Runnable is run on the J2EE worker thread.
    2. When complete, the J2EE worker thread remains active.
  3. The J2EE worker thread now waits for more work to appear on the input queue.


Figure 3. Component-scoped thread pool
Figure 3.  Component-scoped thread pool

Custom thread pools

The Asynchronous Beans WorkManager does not externalize the thread pool, so there is no way to change the default behavior. To implement a component-scoped thread pool, a third-party thread pool must be used in conjunction with the J2EE context switching capability of asynchronous beans.

Several thread pool implementations exist that will work fine with this model. One of the more accepted implementations is Doug Lea's EDU.oswego.cs.dl.util.concurrent.PooledExecutor which will run on J2SE 1.2 and later. This thread pool has evolved into J2SE 5's java.util.concurrent.ThreadPoolExecutor, which has also been back-ported to J2SE 1.4.

Both the PooledExecutor and ThreadPoolExecutor implementations are in the public domain and are downloadable (see Resources).

Below are suggested thread pool implementations, by WebSphere Application Server version:

  • WebSphere Application Server Enterprise V5.0, J2SE 1.3:

    • EDU.oswego.cs.dl.util.concurrent.PooledExecutor
  • WebSphere Busness Integration Server Foundation V5.1 and
    WebSphere Application Server (all editions) V6.0, J2SE 1.4:

    • edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor
    • EDU.oswego.cs.dl.util.concurrent.PooledExecutor
  • WebSphere Application Server (all editions) V6.1, J2SE 5:

    • edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor
    • EDU.oswego.cs.dl.util.concurrent.PooledExecutor
    • java.util.concurrent.ThreadPoolExecutor

These implementations are very similar and utilize a thread factory, which enables plugging-in a customized J2EE-aware thread factory. In this case, the custom thread factory is a wrapper around an Asynchronous Beans EventSource. (See the Concurrent Adapter sample.) These implementations behave similarly to the WebSphere thread pool implementation. If using J2SE 1.4, the back port of java.util.concurrent is recommended, as it has more functionality and will simplify future migration to J2SE 5. If using J2SE 5, using java.util.concurrent directly is suggested.

Asynchronous Beans EventSource

An EventSource is a mechanism of the Asynchronous Beans WorkManager that enables dynamic application of J2EE context from a thread onto any other thread. It provides a way to safely communicate between applications or security contexts in the same process.

For example, if a servlet wants to be notified when a stock price has changed, it can register a listener on a well-known EventSource. When the stock price daemon publishes the change, using a system account, each listener will be notified, but in the listener's security context (Figure 4).


Figure 4. Security context switching with an EventSource
Figure 4. Security context switching with an EventSource

The same technique can be applied to any POJO (plain old Java™ object), which can be wrapped with an EventSource to enable switching the J2EE context of the object for a single method call. EventSources use the java.lang.reflect.Proxy object to wrap each object instance with a specialized, J2EE java.lang.reflect.InvocationHandler. When the proxy is used to invoke the Java object method, the J2EE handler will automatically apply the J2EE context on the thread that was captured when the listener was registered.

This feature is particularly useful when methods are being executed on out-of-scope threads; for example, starting a thread on a thread pool.

Without an EventSource proxy, a new thread will have no J2EE context. The thread pool will instantiate a new java.util.Thread object and call the start() method.

The EventSource enables us to implement a ThreadFactory implementation that can be plugged into a PooledExecutor or ThreadPoolExecutor. The J2EE context of the J2EE component that creates the ThreadFactory will be preserved and reapplied to the thread prior to starting a new worker thread. All the overhead of switching contexts is applied to the thread one time.

Since the EventSource object does not exist in the Commonj WorkManager specification, it is not possible to build a thread factory. A thread factory is only available when using asynchronous beans.


Implementing a thread factory

With this article, we include sample thread factory implementations that enable the use of custom, component-scoped thread pools from J2SE 5, J2SE 1.4 (using the back port of J2SE 5 java.util.concurrent.ThreadPoolExecutor), or with the dl.util.concurrent.PooledExecutor in a WebSphere application. (See the Javadoc for the com.ibm.websphere.sample.concurrentadapter package, included in the download file for details on prerequisites and how to build the WASThreadFactory.)

WASThreadFactory

The WASThreadFactory is the implementation for the ThreadFactory. It uses a WASThreadFactoryBase base class to enable the use of a single implementation for both the J2SE 5 and the dl.concurrent.util version of the ThreadFactory (Figure 5).


Figure 5. WASThreadFactory class diagram
Figure 5. WASThreadFactory class diagram

The WASThreadFactory takes a WorkManager as a parameter on the constructor, and uses it to create an EventSource and register a listener proxy for the WorkManager. When a thread is requested from the WASThreadFactory, the thread will be created using the WorkManager, but will contain the J2EE context of the component that created the WASThreadFactory instance. This is known as a single-context thread pool.

Single-context and multi-context thread pools

When using a custom thread pool such as a ThreadPoolExecutor, it may not be desirable to run work within a single J2EE context. It may be required, for example, to propagate the submitter's security context.

In this case, a J2EE context-aware Executor (ContextExecutor) can be used to attach the current J2EE context to the Runnable prior to execution. Each worker thread in the pool will be primed with the J2EE context of the WASThreadFactory creator, but when using the ContextExecutor, the Runnable will first apply the J2EE context of the submitter to the thread and then remove it when finished.

The same ThreadPoolExecutor is used to directly submit work to the pool that can utilize the default J2EE context. The ContextExecutor wrapper is used to submit work to the ThreadPoolExecutor, but with the submitter's context.


Figure 6. Custom thread pool with default and multi- contexts
Figure 6. Custom thread pool with default and multi- contexts

Usage example: WASThreadFactory

To use the WASThreadFactory, the application must first look up an Asynchronous Beans WorkManager, create a WASThreadFactory instance, and then construct a new thread pool. Working examples using a servlet are available in the sample download file.

// Lookup the WorkManager and construct the WASThreadFactory InitialContext ctx = new InitialContext(); WorkManager wm = (WorkManager)ctx.lookup("java:comp/env/wm/default"); ThreadFactory tf = new WASThreadFactory(wm);  // Create a ThreadPoolExecutor using a bounded buffer BlockingQueue q = new ArrayBlockingQueue(10); ThreadPoolExecutor pool = new ThreadPoolExecutor( 1, 10, 5000, TimeUnit.MILLISECONDS, q, tf);  // Use the submit or execute methods to submit work to the pool pool.submit(myRunnable);

Usage example: ContextExecutor

Using a WASThreadFactory with a ContextExecutor to enable submitting Runnables to a custom thread pool with the submitter's J2EE context is as simple as creating a ContextExecutor instance. A ContextExecutorService can also be used to track the state of the submitted task.

// Create a ThreadPoolExecutor ThreadPoolExecutor pool = new ThreadPoolExecutor( 1, 10, 5000, TimeUnit.MILLISECONDS, q, tf);  // Wrap the ThreadPoolExecutor with a ContextExecutor ContextExecutor cePool = new ContextExecutor(wm, pool);  // Use the ContextExecutor.execute() method to submit work to the pool. cePool.execute(myRunnable)

Installing and running the samples

This article includes three sample applications; one for each of the thread pool implementations described. Each application consists of a single EAR that can be installed on a WebSphere Application Server. Each EAR contains:

  • a Web module (WAR)
  • the ABConcurrencyUtils.jar utility JAR file that contains the code common to all of the samples (including the WASThreadFactory)
  • a utility JAR that includes the specific code for the thread pool implementation.

Each WAR contains three servlets:

  • FactoryTestServlet: A simple example that shows how to create the WASThreadFactory and submit a number of Runnable tasks to it.

  • ABBenchmarkServlet: An example that shows the number of micro-seconds it takes to run an asynchronous bean work object without using the WASThreadFactory.

  • FactoryBenchmarkServlet: An example that shows the number of micro-seconds it takes to run a Runnable using the WASThreadFactory.

Each module includes the source and binaries and can be directly imported into IBM Rational® Application Developer V6. (At the time of this writing, Rational Application Developer does not currently support JDK 5. The JDK5 utility JAR in the JDK5 sample will not compile in Rational Application Developer and must be built separately.)

Prerequisites

Each sample requires asynchronous beans and the WorkManager with JNDI name wm/default; this WorkManager is created by default during installation. The samples have only been tested on the single-server version of WebSphere Application Server. Although these samples have not been tested using WebSphere Application Server Network Deployment, or the unit test environments of Rational Application Developer or WebSphere Studio Application Developer Integration Edition, we expect the samples to operate as expected in these environments.

Sample 1: ABConcurrencyTester_JDK5.ear

This sample can be installed and run on WebSphere Application Server V6.1 and later. It utilizes java.util.concurrent.ThreadPoolExecutor, which is included with J2SE 5.

To run the sample:

  1. Start WebSphere Application Server.
  2. Install ABConcurrencyTester_JDK5.ear using either wsadmin scripting or the administrative console. Use the default options.
  3. Start the ABConcurrencyTester_JDK5 application.
  4. Run the samples using the following URL (where is the IP address or name of your application server host machine, and is the HTTP listener port for the application server):

    http://:/ABConcurrencyTester_JDK5

Sample 2: ABConcurrencyTester_JDK14.ear

This sample can be installed and run on IBM WebSphere Business Integration Server Foundation V5.1 and WebSphere Application Server (all editions) V6.0 and later. It utilizes the java.util.concurrent back port to JDK 1.4.

To run the sample:

  1. Download backport-util-concurrent.jar from http://dcl.mathcs.emory.edu/util/backport-util-concurrent/.
  2. Add backport-util-concurrent.jar to the root of the ABConcurrencyTester_JDK14.ear.
  3. Install the ABConcurrencyTester_JDK14.ear using either wsadmin scripting or the administrative console. Use the default options.
  4. Start the ABConcurrencyTester_JDK14 application.
  5. Run the samples using the following URL (where is the IP address or name of your application server host machine, and is the HTTP listener port for the application server):

    http://:/ABConcurrencyTester_JDK14

Sample 3: ABConcurrencyTester_DL.ear

This sample can be installed on WebSphere Application Server Enterprise V5.0.2, WebSphere Business Integration Server Foundation V5.1, and WebSphere Application Server (all editions) V6.0 and later. It utilizes the dl.util.concurrent package, which runs on JDK 1.2 and later.

To run the sample:

  1. Download and build concurrent.jar using a JDK 1.3 compiler (if deploying to WebSphere Application Server Enterprise V5.0 or later) or a JDK 1.4 compiler (if deploying to WebSphere Business Integration Server Foundation V5.1 or later). The utility comes with an ANT script that will create concurrent.jar. (You can use ws_ant.bat or ws_ant.sh scripts in the application server's bin directory to build the concurrent.jar.) Download the utility from http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html.
  2. Rename concurrent.jar to dl-util-concurrent.jar.
  3. Add dl-util-concurrent.jar to the root of the ABConcurrencyTester_DL.ear.
  4. Install the ABConcurrencyTester_DL.ear using either wsadmin scripting or the administrative console. Use the default options.
  5. Start the ABConcurrencyTester_DL application.
  6. Run the samples using the following URL (where is the IP address or name of your application server host machine and is the HTTP listener port for the application server):

    http://:/ABConcurrencyTester_DL

Conclusion

Asynchronous beans provides an efficient and safe global thread pool that can be used by multiple applications. In the event that specialized thread pools are required, the Asynchronous Beans EventSource can be used to create a ThreadFactory. The J2EE-aware ThreadFactory can be used to create threads primed with a set J2EE context.

The WASThreadFactory, used in the Concurrent Adapter sample in this article, enables J2EE application developers the freedom to utilize any advanced thread usage patterns without sacrificing performance.