April 20, 2024

Java ScheduledThreadPoolExecutor - Scheduling With ExecutorService

ScheduledThreadPoolExecutor in Java adds functionality to schedule commands to run after a given delay, or to execute periodically. Since ScheduledThreadPoolExecutor is an ExecutorService so it uses thread from a thread pool to execute tasks.

Java ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor class is part of Java Executor framework with in the Java concurrent API. This class extends ThreadPoolExecutor and implements ScheduledExecutorService interface.

Java ScheduledThreadPoolExecutor constructors

  • ScheduledThreadPoolExecutor(int corePoolSize)- Creates a new ScheduledThreadPoolExecutor with the given core pool size.
  • ScheduledThreadPoolExecutor(int corePoolSize, RejectedExecutionHandler handler)- Creates a new ScheduledThreadPoolExecutor with the given initial parameters.
  • ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory)- Creates a new ScheduledThreadPoolExecutor with the given initial parameters.
  • ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory, RejectedExecutionHandler handler)- Creates a new ScheduledThreadPoolExecutor with the given initial parameters.

The parameters used in these constructors of the ScheduledThreadPoolExecutor class are as follows-

  • corePoolSize- The number of threads to keep in the pool. These number of threads will always be created even if they are idle, unless allowCoreThreadTimeOut is set.
  • threadFactory- the factory to use when the executor creates a new thread.
  • handler- the handler to use when execution is blocked because the thread bounds and queue capacities are reached.

Creating ScheduledThreadPoolExecutor instance using Executors factory methods

It is recommended to use static factory methods provided by the Executors class to get a ScheduledThreadPoolExecutor rather than creating instances of ThreadPoolExecutor directly using one of the above constructors.

  • newSingleThreadScheduledExecutor()- Creates a single-threaded executor that can schedule commands to run after a given delay, or to execute periodically.
  • newSingleThreadScheduledExecutor(ThreadFactory threadFactory)- Creates a single-threaded executor that can schedule commands to run after a given delay, or to execute periodically.
  • newScheduledThreadPool(int corePoolSize)- Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically.
  • newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory)- Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically.

Scheduling methods in Java ScheduledThreadPoolExecutor

  • schedule(Runnable command, long delay, TimeUnit unit)- Schedules a Runnable task to execute after the given delay.
  • schedule(Callable<V> callable, long delay, TimeUnit unit)- Submits a Callable task to execute after the given delay.
  • scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)- Submits a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period. For example if the initial delay is 5 seconds and the period is 2 seconds then the first task will be executed after the delay of 5 seconds and then periodic execution will happen after every 2 seconds- initialDelay + period, initialDelay + 2 * period and so on.
  • scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)- Submits a periodic action that becomes enabled first after the given initial delay, and subsequently with the given delay between the termination of one execution and the commencement of the next. For example if the initial delay is 5 seconds and the period is 2 seconds then the first task will be executed after the delay of 5 seconds and the second task will be scheduled to run after- (termination of first task + 2 seconds).

All these scheduling methods return a result of type ScheduledFuture which adds delay capabilities by extending Delayed interface apart from Future interface.

Java ScheduledThreadPoolExecutor example – Scheduling Runnable

In this example Executors.newSingleThreadScheduledExecutor() method is used to get a single-threaded executor for scheduling. In the schedule method delay is set as 5 seconds so the task should be executed after that delay.

public class ScheduledThread {
  public static void main(String[] args) {
    ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
    System.out.println("Time before execution started- " + new Date());
    scheduledExecutor.schedule(new Task(), 5, TimeUnit.SECONDS);
    scheduledExecutor.shutdown();
  }
}

class Task implements Runnable{
  @Override
  public void run() {
    System.out.println("Executing task (thread name)- " + Thread.currentThread().getName() +
        "Executed at- " + new Date());
  }
}
Output
Time before execution started- Sat Jan 05 19:11:33 IST 2019
Executing task (thread name)- pool-1-thread-1Executed at- Sat Jan 05 19:11:38 IST 2019

Java ScheduledThreadPoolExecutor’s scheduleAtFixedRate() method example

This example shows how you can do periodic scheduling using scheduleAtFixedRate() method. Executors.newScheduledThreadPool(2) method is used to create a thread pool of two threads. Note the use of awaitTermination() method which ensures tasks are scheduled otherwise shutdown() method won’t let the scheduling of new tasks to happen.

public class ScheduledThread {
  public static void main(String[] args) {
    ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(2);
    System.out.println("Time before execution started- " + new Date());
    scheduledExecutor.scheduleAtFixedRate(new Task(), 5, 2, TimeUnit.SECONDS);
    try {
      // To terminate task execution after 10 seconds
      scheduledExecutor.awaitTermination(10, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    scheduledExecutor.shutdown();
  }
}

class Task implements Runnable{
  @Override
  public void run() {
    System.out.println("Executing task (thread name)- " + Thread.currentThread().getName() +
        " Executed at- " + new Date());
    // adding delay to keep the thread busy
    // so that another thread from pool is used
    try {
      Thread.sleep(1500);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
Output
Time before execution started- Sat Jan 05 19:22:13 IST 2019
Executing task (thread name)- pool-1-thread-1 Executed at- Sat Jan 05 19:22:19 IST 2019
Executing task (thread name)- pool-1-thread-1 Executed at- Sat Jan 05 19:22:21 IST 2019
Executing task (thread name)- pool-1-thread-2 Executed at- Sat Jan 05 19:22:23 IST 2019

As you can see first task is scheduled to run after the initial delay of 5 seconds, later tasks are scheduled to run after delay of 2 seconds.

Java ScheduledThreadPoolExecutor’s scheduleWithFixedDelay() method example

This example shows how you can do periodic scheduling using scheduleWithFixedDelay() method.

public class ScheduledThread {
  public static void main(String[] args) {
    ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(2);
    System.out.println("Time before execution started- " + new Date());
    scheduledExecutor.scheduleWithFixedDelay(new Task(), 5, 2, TimeUnit.SECONDS);
    try {
      // To terminate task execution after 10 seconds
      scheduledExecutor.awaitTermination(10, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    scheduledExecutor.shutdown();
  }
}

class Task implements Runnable{
  @Override
  public void run() {
    System.out.println("Executing task (thread name)- " + Thread.currentThread().getName() +
        " Executed at- " + new Date());
    // adding delay to keep the thread busy
    // so that another thread from pool is used
    try {
      Thread.sleep(1500);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
Output
Time before execution started- Sat Jan 05 19:34:13 IST 2019
Executing task (thread name)- pool-1-thread-1 Executed at- Sat Jan 05 19:34:18 IST 2019
Executing task (thread name)- pool-1-thread-1 Executed at- Sat Jan 05 19:34:22 IST 2019

As you can see first task is scheduled to run after the initial delay of 5 seconds later tasks are scheduled to run after the termination of previous task + 2 seconds.

Java ScheduledThreadPoolExecutor example using constructor

All the examples showed till now use Executors class factory methods which is the recommended way to get a ScheduledThreadPoolExecutor but you can also use constructor of the ScheduledThreadPoolExecutor class.

In the next example ScheduledThreadPoolExecutor instance is created using one of the constructor and then a callable is scheduled to execute after a delay of 3 seconds.

public class ScheduledThread {
  public static void main(String[] args) {
    // creating executor with core pool of 2 threads,  default Thread Factory
    // and handler uses abort policy
    ScheduledThreadPoolExecutor scheduledExecutor = new ScheduledThreadPoolExecutor(2, 
        Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
    // Callable implementation
    Callable<String> c = ()->{
      System.out.println("Executed at- " + new Date());
      return "Executing task";
    };
    System.out.println("Time before execution started- " + new Date());
    // scheduling tasks with callable as param to be
    // executed after a delay of 3 Secs
    ScheduledFuture<String> sf = scheduledExecutor.schedule(c, 3, TimeUnit.SECONDS); 
    try {
      System.out.println("Value- " + sf.get());
    } catch (InterruptedException | ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    scheduledExecutor.shutdown();
  }
}
Output
Time before execution started- Sat Jan 05 19:47:21 IST 2019
Executed at- Sat Jan 05 19:47:24 IST 2019
Value- Executing task

That's all for the topic Java ScheduledThreadPoolExecutor - Scheduling With ExecutorService. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment