Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Building Multithreaded Java Applications : Page 3

The Java concurrency utilities released in Java 5.0 simplified the development of multithreaded applications through their simple-to-use but robust and powerful API.


advertisement

Defining Asynchronous Task Implementation

The executor executes submitted asynchronous tasks, which perform the actual business logic. To submit a task to the executor, the ExecutorService interface provides overloaded submit methods, which accept Runnable or Callable object types.

The Runnable task type is useful in cases where:

  • The task does not need to return any result on completion.
  • There is no need to throw an application-specific checked exception if the run() method encounters an exception.
  • Porting the existing legacy classes that implement the Runnable interface is required.

The Callable task type provides more flexibility and provides the following advantages:

  • The task can return user-defined objects as results.
  • The task can throw user-defined checked exceptions.



You need to implement run() and call() methods for Runnable and Callable task types, respectively.

The OrderProcessorCallable class in Listing 2 implements the Callable interface and specifies an Integer as the result object. The constructor takes the task object name and the BlockingQueue for retrieving the orders to be processed. The call() method keeps on polling the BlockingQueue for order value objects and processes any it finds. If there is no order to process, the call() method sleeps for some time and polls it again.

The infinite loop in the call method is useful in this application scenario because there is no need to create and submit new tasks to the ThreadPoolExecutor again and again for each order object.

public Integer call() throws OrderProcessingException { while (running) { // check if current Thread is interrupted checkInterruptStatus(); // poll for OrderVO from blocking queue and do // order processing here ... } // return result return processedCount; }

Notice that the asynchronous task implementation runs continuously for the application's lifetime. In most applications, however, asynchronous task implementation performs its required operation and returns immediately.

Handling Thread Interrupts

The call method implementation uses the checkInterruptStatus method to perform frequent checks on executing thread interruptions. This is required because to force task cancellation, ThreadPoolExecutor sends an interrupt to the thread. Failing to check interrupt status could result in that particular thread never returning. The following checkInterruptStatus method checks the interrupt statuses of running threads and throws OrderProcessingException if a thread is interrupted:

private void checkInterruptStatus() throws OrderProcessingException { if (Thread.interrupted()) { throw new OrderProcessingException("Thread was interrupted"); } }

For task implementations, it is generally a good practice to throw an exception and terminate task execution when a running thread is interrupted. However, based on the order-processing application's requirements, ignoring the thread interrupt may be appropriate in this case.



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap