ScheduledExecutorService
is an interface that extends ExecutorService
and provides methods for scheduling tasks to run after a delay or periodically.newSingleThreadScheduledExecutor()
method creates an executor that uses a single worker thread to execute scheduled tasks sequentially.<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.17.0</version> </dependency>Note: The Apache Commons Lang3 dependency is included for the
BasicThreadFactory
class,
which provides convenient thread naming and daemon thread configuration.
While Java's built-in Executors.newSingleThreadExecutor
works without additional dependencies,
using a custom ThreadFactory allows better thread management and debugging.import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.apache.commons.lang3.concurrent.BasicThreadFactory; public class MainClass { public static void main(String[] args) throws InterruptedException { // The time to wait before the first execution final long INITIAL_DELAY = 500l; // The time to wait between the completion of one execution and the start of the next final long DELAY = 1000l; final String namingPattern = "_newSingleThreadScheduledExecutor"; final BasicThreadFactory.Builder builder = new BasicThreadFactory.Builder(); // Configures thread properties // namingPattern sets custom thread names // daemon(true) makes threads daemon threads (JVM can exit even if these threads are running) final BasicThreadFactory basicThreadFactory = builder.namingPattern(namingPattern).daemon(true).build(); final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(basicThreadFactory); final Runnable runnable = () -> System.out.println(Thread.currentThread().getName() + ": Hello!"); // Schedules repeated execution with a fixed delay between the end of one execution and the start of the next scheduledExecutorService.scheduleWithFixedDelay(runnable, INITIAL_DELAY, DELAY, TimeUnit.MILLISECONDS); // Blocks until all tasks complete or timeout occurs scheduledExecutorService.awaitTermination(5000l, TimeUnit.MILLISECONDS); // Initiates orderly shutdown - no new tasks accepted, but previously submitted tasks continue scheduledExecutorService.shutdown(); } }Output:
_newSingleThreadScheduledExecutor: Hello! _newSingleThreadScheduledExecutor: Hello! _newSingleThreadScheduledExecutor: Hello! _newSingleThreadScheduledExecutor: Hello! _newSingleThreadScheduledExecutor: Hello!