The road so far….

September 21, 2010

TIP! : use ScheduledExecutor instead of Thread for polling or infinite loops

Filed under: java — Tags: — Rahul Sharma @ 10:34 pm

Often we have the requirement of polling/ long or infinite  running loops that should continually run and then break on a certain condition. These loops are often constructed using the Runnable interface and are scheduled as separated threads using the  Thread class.

A typical code looks some thing like this:

public class TestSchedularService {
 long sleep = 500;

 @Test
 public void testLoop() throws Exception {
 PollingThread infiniteLoop = new PollingThread(500);
 Thread loopingTh = new Thread(infiniteLoop);
 loopingTh.start();
 Thread.sleep(2 * sleep);
 loopingTh.interrupt();
 }
}

class PollingThread implements Runnable {
private long sleep;
PollingThread(long sleep) {
this.sleep = sleep;
}
public void run() {
System.out.println("Starting to Poll");
try {
poll();
} catch (InterruptedException e) {
System.out.println("Stopping to Poll");
e.printStackTrace();
}
}
private void poll() throws InterruptedException {
 int count = 0;
 while (true) {
System.out.println("iteration :" + (count++));
Thread.sleep(sleep);
 }}
}

There are a couple of issues here with this code. We have to use Thread.sleep in such tasks so that the  CPU can schedule some other tasks. Moreover to break such a loop e.g. while stopping the looping thread, we have to use  Thread.interrupt API and consequently rely on the InterruptedException that gets thrown.

The use of Exceptions to break the loop is not considered the best use of Exceptions,  they are meant for exceptional circumstances and not for regular business implementations.  More over if I look at the above example I see that my business is in function poll(), the system.out.println line, but I have to write a lot of infrastructure code to make this piece of code work in a pooling thread.

ScheduledExecutorService

The ScheduledExecutorService is an Executor that can be used to schedule tasks. The tasks can be scheduled for a single run, at some point of time, or multiple runs, at some delay. In order to use the Executor  we can create a Runnable task and the same task can be scheduled for multiple runs at some specified delay. These tasks when scheduled give back a Future object that can be used to stop the task if it has not completed or return some data(use Callable instead of Runnable) etc.  The tasks can also be canceled or stopped by shutting down the Executor.

The same code that I wrote for the thread example can be written using the SchedularExecutorService API in the following  manner :

public class TestSchedularService {
 long sleep = 500;

 @Test
 public void testLoop2() throws Exception {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture future = executor.scheduleWithFixedDelay(new PollingService(), 0, sleep,TimeUnit.MILLISECONDS);
Thread.sleep(2 * sleep);
future.cancel(false);
executor.shutdown();
 }
}

class PollingService implements Runnable {
 private int count = 0;
public void run() {
System.out.println("iteration :" + (count++));
 }
}

The above piece of code does the same task as done previously using Threads . The approach adopted here is cleaner and does the intended task with minimum infrastructure code.

Advertisements

4 Comments »

  1. Imho there is nothing wrong with using a Thread for a loop or an task that uses a delay. With the ScheduledExecutor you have more options, but as long as you don’t need them, a normal thread is perfectly ok if used correctly.

    Peter Veentjer
    Multiverse: Software Transactional Memory for Java
    http://multiverse.codehaus.org

    Comment by Peter Veentjer — September 24, 2010 @ 11:39 am

    • Yes, you can do everything with Thread class but imho ScheduledExecutor offers much more options to work with. Using these options we can design better solutions, atleast they are more readable.

      Comment by Rahul Sharma — September 24, 2010 @ 9:42 pm

  2. […] TIP! : use ScheduledExecutor instead of Thread for polling or infinite loops « The road so far…. […]

    Pingback by Blog bookmarks 09/26/2010 « My Diigo bookmarks — September 26, 2010 @ 10:03 am

  3. Or even easier, with many different timers all sharing one event thread:
    new javax.swing.Timer(1000, new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    your code here
    }
    }).start();

    Comment by George — April 27, 2013 @ 3:58 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: