java.util.concurrent.ScheduledThreadPoolExecutor Example
In this example, we shall be demonstrating how we can use the java.util.concurrent.ScheduledThreadPoolExecutor
Class to schedule some periodic Tasks at fixed rate or fixed delay.
1. Timer
Timer task is used also used to schedule activities. However, the Timer
object can run only Task at a time. As a result of which, if the previous task is taking a more to time to execute, the consequent tasks get delayed.
2. ScheduledThreadPoolExecutor to the rescue!
To avoid the above problem, we use the ScheduledThreadPoolExecutor
Class which can run more than one task in parallel. The minimum number of Threads(i.e. corepoolsize) that can be passed at the time of creation of the ScheduledThreadPoolExecutor
.
The scheduleXXXX
methods of the ScheduledThreadPoolExecutor accept instance of Runnable
or Callable
. We can get the result of computation of the Callable
instance via get()
method of ScheduledFuture
.
We will have a look at an example, to see how we can get the ScheduledThreadPoolExecutor
Class to schedule the delayed activities.
ScheduledThreadPoolExecutorExample.java:
package com.javacodegeeks.examples; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; /** * @author Chandan Singh * */ public class ScheduledThreadPoolExecutorExample { public static void main(String[] args) throws InterruptedException, ExecutionException { Runnable runnabledelayedTask = new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+" is Running Delayed Task"); } }; Callable callabledelayedTask = new Callable() { @Override public String call() throws Exception { return return "GoodBye! See you at another invocation..."; } }; ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(4); scheduledPool.scheduleWithFixedDelay(runnabledelayedTask, 1, 1, TimeUnit.SECONDS); ScheduledFuture sf = scheduledPool.schedule(callabledelayedTask, 4, TimeUnit.SECONDS); String value = sf.get(); System.out.println("Callable returned"+value); scheduledPool.shutdown(); System.out.println("Is ScheduledThreadPool shutting down? "+scheduledPool.isShutdown()); } }
OUTPUT:
pool-1-thread-1 is Running Delyed Task pool-1-thread-2 is Running Delyed Task pool-1-thread-3 is Running Delyed Task Callable returned : GoodBye! See you at another invocation... Is ScheduledThreadPool shutting down? true
The ScheduledThreadPoolExecutor
instance is retrieved via static factory method of Executors
Class with a core Pool Size of 5. Then we schedule the Runnable
and Callable
class instances. The runnable task(runnabledelayedTask) starts execution after exactly one second and is then run after delay of one second. The callable task starts execution after 4 seconds. However, the task cannot be invoked again because the repeatable return type of callable cannot be expressed easily.
3. shutdownNow() Vs shutdown()
The shutdown()
method indicates that the shutdown has been invoked on the Executor
and hence no further tasks will be added to the DelayedPool
(used by the ScheduledThreadPoolExecutor
class internally). However, the tasks already submitted in the Queue will be allowed to complete.
On the other hand, the shutdownNow()
method tries to kill the currently running tasks and also stops the processing of the queued tasks and returns the List
that were awaiting execution.
4. isTerminated() Vs isShutdown()
isShutdown()
indicates that the Executor is in the process of shutting down, however, not all tasks have finished execution.
isShutdown()
on the other hand, means that all the threads have finished execution.
5. scheduleWithFixedDelay() vs scheduleAtFixedRate()
scheduleAtFixedRate(...)
treats the delay as the difference between the start of the two tasks.(i.e. Invocation at regular intervals)
scheduleWithFixedDelay(...)
treats the delay as the difference between the end of one task and the start of next task.
If you want to provide custom implementation of the way in which the execute method is called, you may choose to over-ride the protected
decorateTask(..)
method.One important point to note about
ScheduledThreadPoolExecutor
is that once a task encounters exception, its subsequent invocations are silently suppressed.Conclusion
Thus we have studied about the java.util.concurrent.ScheduledThreadPoolExecutor
Class and what benefits, it offers as compared to the Timer
class.
You can download the source code of this example here: ScheduledThreadPoolExecutorDemo.zip
in the section 4. isTerminated() Vs isShutdown(), you used isShutdown() twice