Saturday, July 6, 2013

ScheduledThreadPoolExecutor in examples.

ScheduledThreadPoolExecutor extends capabilities of ThreadPoolExecutor (class diagram here) and makes it possible to schedule tasks execution.


ScheduledExecutorService interface gives new methods:

- two of them for scheduling action (Runnable or Callable) to execute just ones:

schedule (Callable<V> callable, long delay, TimeUnit unit): <V> ScheduledFuture<V>


schedule (Runnable command, long delay, TimeUnit unit): ScheduledFuture<?>


- and two others for periodic task execution:

scheduleAtFixedRate (Runnable command, long initialDelay, long period, TimeUnit unit): ScheduledFuture<?>


scheduleWithFixedDelay (Runnable command, long initialDelay, long delay, TimeUnit unit): ScheduledFuture<?>


Let’s see how they work.

1. Scheduled not repeated tasks with delay


In the following example we schedule 5 tasks that should be started not earlier than in 10 seconds. This is our Runnable task (it prints thread name, time of execution and input data):

[code language="java" gutter="true" tabsize="4"]
public class RunnableTask implements Runnable {
private String data;

public RunnableTask (String data) {
this.data = data;
}

@Override
public void run() {
//prints thread name, time and data
System.out.println(Thread.currentThread().getName() + " processes at " +
SimpleDateFormat.getTimeInstance().format(new Date()) + " : " + data);
try {
//sleep 15 seconds
Thread.sleep(15000);
} catch (InterruptedException e) {
//some exception handler
}
}
}
[/code]

Then we create ScheduledThreadPoolExecutor:

[code language="java" gutter="true" tabsize="4"]
public class ScheduledDataProcessor {

public void processData(List<String> someData) throws InterruptedException {
//prints start time
System.out.println("Start at: " + SimpleDateFormat.getTimeInstance().format(new Date()));

//creates pool of 3 threads
ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(3);

for(String data: someData){
//schedule task that should be executed with delay 10 seconds
threadPool.schedule(new RunnableTask(data), 10, TimeUnit.SECONDS);
}

//shutdown to reclaim resources (threads in the pool will exist until shutdown)
threadPool.shutdown();
}[/code]

and run it:

[code language="java" firstline="25" gutter="true" tabsize="4"]
public static void main(String[] args) throws InterruptedException {
//list with data for test
List<String> data = new ArrayList<String>();
for(int i=1; i<6; i++){
data.add("Data" + i);
}

//data processing
ScheduledDataProcessor dataProcessor = new ScheduledDataProcessor();
dataProcessor.processData(data);
}
}[/code]

In the result you can see that tasks were executed with 10 seconds delay:

schedule result

2. Scheduled periodical tasks.


2.1. scheduleAtFixedRate (Runnable command, long initialDelay, long period, TimeUnit unit): ScheduledFuture<?>


Function works according to the rule: first execution will be started after initialDelay and all next repeatitions after specified period:


work scheme of scheduleAtFixedRate method


Example:

Add into our Runnable task print of start and end execution time. And modify ScheduledThreadPoolExecutor:

[code language="java" gutter="true" tabsize="4"]
public class ScheduledDataProcessor {

public void processData(){
//print start time
System.out.println("Start at: " + SimpleDateFormat.getTimeInstance().format(new Date()));

//creates pool of 2 threads
ScheduledThreadPoolExecutor threadPool = (ScheduledThreadPoolExecutor)Executors.newScheduledThreadPool(2);

//schedules task which first execution will be in 5 seconds
//and repetition with period 20 seconds
threadPool.scheduleAtFixedRate(new RunnableTask("test1"), 5, 20, TimeUnit.SECONDS);

//here should be shutdown that correspond to business logic
}

public static void main(String[] args){
//data processing
ScheduledDataProcessor dataProcessor = new ScheduledDataProcessor();
dataProcessor.processData();
}
}[/code]

Result:

scheduleAtFixedRate result

2.2. scheduleWithFixedDelay (Runnable command, long initialDelay, long delay, TimeUnit unit): ScheduledFuture<?>


Function works according to the rule: executes each task periodically with fixed delay between end point of one task and start point of other. First execution will be started after initialDelay:


work scheme of scheduleWithFixedDelaymethod


Example:


Let's replace in the previous example line



[code language="java" firstline="10" gutter="true" tabsize="4"]
//schedules task which first execution will be in 5 seconds
//and repetition with period 20 seconds
threadPool.scheduleAtFixedRate(new RunnableTask("test1"), 5, 20, TimeUnit.SECONDS);
[/code]

 by the next line:



[code language="java" firstline="10" gutter="true" tabsize="4"]
//schedules task which first execution will be in 5 seconds
//and repetition with delay 5 seconds
threadPool.scheduleWithFixedDelay(new RunnableTask("test1"), 5, 5, TimeUnit.SECONDS);
[/code]

In the result:


scheduleWithFixedDelay result

No comments:

Post a Comment