How to do it...

Follow these steps to implement the example:

  1. Create a class named MyScheduledTask parameterized by a generic type named V. It extends the FutureTask class and implements the RunnableScheduledFuture interface:
        public class MyScheduledTask<V> extends FutureTask<V>
implements RunnableScheduledFuture<V> {
  1. Declare a privateRunnableScheduledFuture attribute named task:
        private RunnableScheduledFuture<V> task;
  1. Declare a privateScheduledThreadPoolExecutor class named executor:
        private ScheduledThreadPoolExecutor executor;
  1. Declare a private long attribute named period:
        private long period;
  1. Declare a private long attribute named startDate:
        private long startDate;
  1. Implement a constructor of the class. It receives the Runnable object that is going to be executed by a task, the result that will be returned by this task, the RunnableScheduledFuture task that will be used to create the MyScheduledTask object, and the ScheduledThreadPoolExecutor object that is going to execute the task. Call the constructor of its parent class and store the task and executor attributes:
        public MyScheduledTask(Runnable runnable, V result,
RunnableScheduledFuture<V> task,
ScheduledThreadPoolExecutor executor) {
super(runnable, result);
this.task=task;
this.executor=executor;
}
  1. Implement the getDelay() method. If the task is periodic and the startDate attribute has a value other than zero, calculate the returned value as the difference between the startDate attribute and the actual date. Otherwise, return the delay of the original task stored in the task attribute. Don't forget that you have to return the result in the time unit passed as a parameter:
        @Override 
public long getDelay(TimeUnit unit) {
if (!isPeriodic()) {
return task.getDelay(unit);
} else {
if (startDate==0){
return task.getDelay(unit);
} else {
Date now=new Date();
long delay=startDate-now.getTime();
return unit.convert(delay, TimeUnit.MILLISECONDS);
}
}
}
  1. Implement the compareTo() method. Call the compareTo() method of the original task:
        @Override 
public int compareTo(Delayed o) {
return task.compareTo(o);
}
  1. Implement the isPeriodic() method. Call the isPeriodic() method of the original task:
        @Override 
public boolean isPeriodic() {
return task.isPeriodic();
}
  1. Implement the run() method. If it's a periodic task, you have to update its startDate attribute with the start date of the next execution of the task. Calculate it as the sum of the actual date and period. Then, add the task again to the queue of the ScheduledThreadPoolExecutor object:
        @Override 
public void run() {
if (isPeriodic() && (!executor.isShutdown())) {
Date now=new Date();
startDate=now.getTime()+period;
executor.getQueue().add(this);
}
  1. Print a message to the console with the actual date. Execute the task calling the runAndReset() method and then print another message to the console with the actual date:
          System.out.printf("Pre-MyScheduledTask: %s
",new Date()); 
System.out.printf("MyScheduledTask: Is Periodic: %s ",
isPeriodic());
super.runAndReset();
System.out.printf("Post-MyScheduledTask: %s ",new Date());
}
  1. Implement thesetPeriod() method to establish the period of this task:
        public void setPeriod(long period) { 
this.period=period;
}
  1. Create a class named MyScheduledThreadPoolExecutor to implement a ScheduledThreadPoolExecutor object that executes MyScheduledTask tasks. Specify that this class extends the ScheduledThreadPoolExecutor class:
        public class MyScheduledThreadPoolExecutor extends
ScheduledThreadPoolExecutor {
  1. Implement a constructor of the class that merely calls the constructor of its parent class:
        public MyScheduledThreadPoolExecutor(int corePoolSize) { 
super(corePoolSize);
}
  1. Implement the decorateTask() method. It receives the Runnable object that is going to be executed as a parameter and the RunnableScheduledFuture task that will execute this Runnable object. Create and return a MyScheduledTask task using these objects to construct them:
        
@Override
protected <V> RunnableScheduledFuture<V> decorateTask(
Runnable runnable,
RunnableScheduledFuture<V> task) {
MyScheduledTask<V> myTask=new MyScheduledTask<V>(runnable,
null, task,this);
return myTask;
}
  1. Override the scheduledAtFixedRate() method. Call the method of its parent class, convert the returned object into a MyScheduledTask object, and establish the period of that task using the setPeriod() method:
        @Override 
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay, long period, TimeUnit unit) {
ScheduledFuture<?> task= super.scheduleAtFixedRate(command,
initialDelay, period, unit);
MyScheduledTask<?> myTask=(MyScheduledTask<?>)task;
myTask.setPeriod(TimeUnit.MILLISECONDS.convert(period,unit));
return task;
}
  1. Create a class named Task that implements the Runnable interface:
        public class Task implements Runnable {
  1. Implement the run() method. Print a message at the start of the task, put the current thread to sleep for 2 seconds, and print another message at the end of the task:
        @Override 
public void run() {
System.out.printf("Task: Begin. ");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Task: End. ");
}
  1. Implement the main class of the example by creating a class named Main with a main() method:
        public class Main { 

public static void main(String[] args) throws Exception{
  1. Create a MyScheduledThreadPoolExecutor object named executor. Use 4 as a parameter to have two threads in the pool:
        MyScheduledThreadPoolExecutor executor=new
MyScheduledThreadPoolExecutor(4);
  1. Create a Task object named task. Write the actual date in the console:
        Task task=new Task(); 
System.out.printf("Main: %s ",new Date());
  1. Send a delayed task to the executor using the schedule() method. The task will be executed after a 1-second delay:
        executor.schedule(task, 1, TimeUnit.SECONDS);
  1. Put the main thread to sleep for 3 seconds:
        TimeUnit.SECONDS.sleep(3);
  1. Create another Task object. Print the actual date in the console again:
        task=new Task(); 
System.out.printf("Main: %s ",new Date());
  1. Send a periodic task to the executor using the scheduleAtFixedRate() method. The task will be executed after a 1-second delay and then it will be executed every 3 seconds:
        executor.scheduleAtFixedRate(task, 1, 3, TimeUnit.SECONDS);
  1. Put the main thread to sleep for 10 seconds:
        TimeUnit.SECONDS.sleep(10);
  1. Shut down the executor using the shutdown() method. Wait for the finalization of the executor using the awaitTermination() method:
        executor.shutdown(); 
executor.awaitTermination(1, TimeUnit.DAYS);
  1. Write a message in the console indicating the end of the program:
        System.out.printf("Main: End of the program.
");
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.174.0