ScheduledThreadPoolExecutor – Task Scheduling with Executors

The Java Executor Framework provides the ThreadPoolExecutor class to execute Callable and Runnable tasks with a pool of threads, which avoid you writing lots of boiler plate complex code. The way executors work is when you send a task to the executor, it’s executed as soon as possible. But there may be used cases when you are not interested in executing a task as soon as possible. Rather You may want to execute a task after a period of time or to execute a task periodically. For these purposes, the Executor framework provides the ScheduledThreadPoolExecutor class.

Task to be executed

Let’s write a very basic task which we can use for demo purpose.

class Task implements Runnable
{
	private String name;

	public Task(String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}

	@Override
	public void run() 
	{
		try {
			System.out.println("Doing a task during : " + name + " - Time - " + new Date());
		} 
		catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Execute a task after a period of time

package com.howtodoinjava.demo.multithreading;

import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledThreadPoolExecutorExample
{
	public static void main(String[] args) 
	{
		ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
		Task task1 = new Task ("Demo Task 1");
		Task task2 = new Task ("Demo Task 2");
		
		System.out.println("The time is : " + new Date());
		
		executor.schedule(task1, 5 , TimeUnit.SECONDS);
		executor.schedule(task2, 10 , TimeUnit.SECONDS);
		
		try {
		      executor.awaitTermination(1, TimeUnit.DAYS);
		} catch (InterruptedException e) {
		      e.printStackTrace();
		}
		
		executor.shutdown();
	}
}

Output:

The time is : Wed Mar 25 16:14:07 IST 2015
Doing a task during : Demo Task 1 - Time - Wed Mar 25 16:14:12 IST 2015
Doing a task during : Demo Task 2 - Time - Wed Mar 25 16:14:17 IST 2015

As with class ThreadPoolExecutor, to create a scheduled executor, Java recommends the utilization of the Executors class. In this case, you have to use the newScheduledThreadPool() method. You have passed the number 1 as a parameter to this method. This parameter is the number of threads you want to have in the pool.

To execute a task in this scheduled executor after a period of time, you have to use the schedule() method. This method receives the following three parameters:

  • The task you want to execute
  • The period of time you want the task to wait before its execution
  • The unit of the period of time, specified as a constant of the TimeUnit class

Also note that You can also use the Runnable interface to implement the tasks, because the schedule() method of the ScheduledThreadPoolExecutor class accepts both types of tasks.

Moreover ,although the ScheduledThreadPoolExecutor class is a child class of the ThreadPoolExecutor class and, therefore, inherits all its features, Java recommends the utilization of ScheduledThreadPoolExecutor only for scheduled tasks.

Finally, you can configure the behavior of the ScheduledThreadPoolExecutor class when you call the shutdown() method and there are pending tasks waiting for the end of their delay time. The default behavior is that those tasks will be executed despite the finalization of the executor. You can change this behavior using the setExecuteExistingDelayedTasksAfterShutdownPolicy() method of the ScheduledThreadPoolExecutor class. With false, at the time of shutdown(), pending tasks won’t get executed.

Execute a task periodically

Now let’s learn how to use ScheduledThreadPoolExecutor to schedule a periodic task.

public class ScheduledThreadPoolExecutorExample
{
	public static void main(String[] args) 
	{
		ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
		Task task1 = new Task ("Demo Task 1");
		
		System.out.println("The time is : " + new Date());
		
		ScheduledFuture<?> result = executor.scheduleAtFixedRate(task1, 2, 5, TimeUnit.SECONDS);
		
		try {
	        TimeUnit.MILLISECONDS.sleep(20000);
	    } 
		catch (InterruptedException e) {
	        e.printStackTrace();
	    }
		
		executor.shutdown();
	}
}

Output:

The time is : Wed Mar 25 16:20:12 IST 2015
Doing a task during : Demo Task 1 - Time - Wed Mar 25 16:20:14 IST 2015
Doing a task during : Demo Task 1 - Time - Wed Mar 25 16:20:19 IST 2015
Doing a task during : Demo Task 1 - Time - Wed Mar 25 16:20:24 IST 2015
Doing a task during : Demo Task 1 - Time - Wed Mar 25 16:20:29 IST 2015

In this example, we have created ScheduledExecutorService instance just like above example using newScheduledThreadPool() method. Then we have used the scheduledAtFixedRate() method. This method accepts four parameters:

  • the task you want to execute periodically,
  • the delay of time until the first execution of the task,
  • the period between two executions,
  • and the time unit of the second and third parameters.

An important point to consider is that the period between two executions is the period of time between these two executions that begins. If you have a periodic task that takes 5 seconds to execute and you put a period of 3 seconds, you will have two instances of the task executing at a time.

ScheduledThreadPoolExecutor provides other methods to schedule periodic tasks. It is the scheduleWithFixedRate() method. It has the same parameters as the scheduledAtFixedRate() method, but there is a difference worth noticing. In the scheduledAtFixedRate() method, the third parameter determines the period of time between the starting of two executions. In the scheduledWithFixedRate() method, parameter determines the period of time between the end of an execution of the task and the beginning of the next execution.

You can also configure the behavior of an instance of the ScheduledThreadPoolExecutor class with the shutdown() method. The default behavior is that the scheduled tasks finish when you call that method. You can change this behavior using the setContinueExistingPeriodicTasksAfterShutdownPolicy() method of the ScheduledThreadPoolExecutor class with a true value. The periodic tasks won’t finish upon calling the shutdown() method.

Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

11 thoughts on “ScheduledThreadPoolExecutor – Task Scheduling with Executors”

  1. is there any way we can change schedule interval after he start of program. For example, I want to change execution time of a task from 1 AM daily to 2 AM daily.

    Reply
  2. Thanks for your post , these posts on individual topics are very helpful in understanding and later we can mix them for the desired functionality.
    Just one correction, In the Note section you might have done Typo and hence it shows “scheduledWithFixedRate” instead of “scheduleWithFixedDelay”.

    Reply
    • “If you have a periodic task that takes 5 seconds to execute and you put a period of 3 seconds, you will have two instances of the task executing at a time.” – No two tasks execute at the same time. [Please refer to 5.3 this post] In this case, the subsequent execution happens at every 5 seconds though the delay is 3 seconds. Thanks.

      Reply
  3. The 1st example, should we put
    executor.shutdown();
    before
    executor.awaitTermination(1, TimeUnit.DAYS);

    so the executor can exit after all tasks are done rather than waiting for a day?

    Reply
    • awaitTermination(long timeout, TimeUnit unit)
      Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.

      Reply
  4. IN Execute a task periodically program , the output has 4 statements. Is there any reason why the task executed for 4 times ? Can we configure how many times it should execute ?

    Reply
        • It will run indefinitely and we are only forcing it to stop executing after 4 times using sleep method.If we change the seconds in sleep from 20 to 30 then it will run 6 times and it will shutdown. Hope u guys Understand!!!!

          Reply

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.