How to do it...

Follow these steps to implement the example:

  1. Create a class named MyExecutor that extends the ThreadPoolExecutor class:
        public class MyExecutor extends ThreadPoolExecutor {
  1. Declare a private ConcurrentHashMap attribute parameterized by the String and Date classes, named startTimes:
        private final ConcurrentHashMap<Runnable, Date> startTimes;
  1. Implement the constructor for the class. Call a constructor of the parent class using the super keyword and initialize the startTime attribute:
        public MyExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
workQueue);
startTimes=new ConcurrentHashMap<>();
}
  1. Override the shutdown() method. Write in the console information about the executed, running, and pending tasks. Then, call the shutdown() method of the parent class using the super keyword:
        @Override 
public void shutdown() {
System.out.printf("MyExecutor: Going to shutdown. ");
System.out.printf("MyExecutor: Executed tasks: %d ",
getCompletedTaskCount());
          System.out.printf("MyExecutor: Running tasks: %d
",
getActiveCount()); System.out.printf("MyExecutor: Pending tasks: %d ",
getQueue().size());
super.shutdown();
}
  1. Override the shutdownNow() method. Write in the console information about the executed, running, and pending tasks. Then, call the shutdownNow() method of the parent class using the super keyword:
        @Override 
public List<Runnable> shutdownNow() {
System.out.printf("MyExecutor: Going to immediately
shutdown. ");
System.out.printf("MyExecutor: Executed tasks: %d ",
getCompletedTaskCount());
System.out.printf("MyExecutor: Running tasks: %d ",
getActiveCount());
System.out.printf("MyExecutor: Pending tasks: %d ",
getQueue().size());
return super.shutdownNow();
}
  1. Override the beforeExecute() method. Write a message in the console with the name of the thread that is going to execute the task and the hash code of the task. Store the start date in HashMap using the hash code of the task as the key:
        @Override 
protected void beforeExecute(Thread t, Runnable r) {
System.out.printf("MyExecutor: A task is beginning: %s : %s ",
t.getName(),r.hashCode());
startTimes.put(r, new Date());
}
  1. Override the afterExecute() method. Write a message in the console with the result of the task and calculate the running time of the task after subtracting the start date of the task stored in HashMap of the current date:
          @Override 
protected void afterExecute(Runnable r, Throwable t) {
Future<?> result=(Future<?>)r;
try {
System.out.printf("********************************* ");
System.out.printf("MyExecutor: A task is finishing. ");
              System.out.printf("MyExecutor: Result: %s
",
result.get());
Date startDate=startTimes.remove(r);
Date finishDate=new Date();
long diff=finishDate.getTime()-startDate.getTime();
System.out.printf("MyExecutor: Duration: %d ",diff);
System.out.printf("********************************* ");
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
  1. Create a class named SleepTwoSecondsTask that implements the Callable interface parameterized by the String class. Implement the call() method. Put the current thread to sleep for 2 seconds and return the current date converted into a String type:
        public class SleepTwoSecondsTask implements Callable<String> { 

public String call() throws Exception {
TimeUnit.SECONDS.sleep(2);
return new Date().toString();
}

}
  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) {
  1. Create a MyExecutor object named myExecutor:
        MyExecutor myExecutor=new MyExecutor(4, 8, 1000,
TimeUnit.MILLISECONDS,
new LinkedBlockingDeque<Runnable>());
  1. Create a list of Future objects parameterized by the String class to store the resultant objects of the tasks you're going to send to the executor:
        List<Future<String>> results=new ArrayList<>();
  1. Submit 10 Task objects:
        for (int i=0; i<10; i++) { 
SleepTwoSecondsTask task=new SleepTwoSecondsTask();
Future<String> result=myExecutor.submit(task);
results.add(result);
}
  1. Get the result of the execution of the first five tasks using the get() method. Write them in the console:
        for (int i=0; i<5; i++){ 
try {
String result=results.get(i).get();
System.out.printf("Main: Result for Task %d : %s ",
i,result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
  1. Finish the execution of the executor using the shutdown() method:
        myExecutor.shutdown();
  1. Get the result of the execution of the last five tasks using the get() method. Write them in the console:
        for (int i=5; i<10; i++){ 
try {
String result=results.get(i).get();
System.out.printf("Main: Result for Task %d : %s ",
i,result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
  1. Wait for the completion of the executor using the awaitTermination() method:
        try { 
myExecutor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
  1. Write a message indicating the end of the execution 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.144.97.126