Sinobu

kiss

Scheduler

A custom scheduler implementation based on the ScheduledExecutorService interface, using virtual threads to schedule tasks with specified delays or intervals.

This class extends AbstractExecutorService and implements ScheduledExecutorService to provide scheduling capabilities with a task queue and delay mechanisms. It leverages DelayQueue to manage task execution times, and uses virtual threads to run tasks in a lightweight and efficient manner.

Core Functionality

  • Allows scheduling of tasks with delays or fixed intervals.
  • Supports scheduling based on cron expressions for periodic execution.
  • Uses virtual threads to minimize memory consumption and resource overhead.

Thread Management

Virtual threads are created in an "unstarted" state when tasks are registered. Execution is delayed until the scheduled time, reducing memory usage. Once the scheduled time arrives, the virtual threads are started and the tasks are executed. If the task is periodic, it is rescheduled after completion.

Usage

You can use the following methods to schedule tasks:

Task Lifecycle

The scheduler maintains internal counters to track running tasks and completed tasks using AtomicLong. The task queue is managed through DelayQueue, which ensures tasks are executed at the correct time. Each task is wrapped in a custom Task class that handles execution, cancellation, and rescheduling (for periodic tasks).

Shutdown and Termination

The scheduler can be shut down using the #shutdown() or #shutdownNow() methods, which stops the execution of any further tasks. The #awaitTermination(long, TimeUnit) method can be used to block until all tasks are finished executing after a shutdown request.

runsSetTask

The the running task manager.

queueDelayQueueTask

The task queue.

Scheduler()

Create Scheduler without the specified concurrency limit.

Scheduler(intlimit)

intlimit

Controls the number of tasks that can be executed concurrently.

Create Scheduler with the specified concurrency limit.

executeTask(Task?task)Task

Task?task
Task

Execute the task.

schedule(Runnablecommand, longdelay, TimeUnitunit)ScheduledFuture?

Runnablecommand
longdelay
TimeUnitunit
ScheduledFuture?

schedule(CallableVcommand, longdelay, TimeUnitunit)ScheduledFutureV

V
CallableVcommand
longdelay
TimeUnitunit
ScheduledFutureV

scheduleAtFixedRate(Runnablecommand, longdelay, longinterval, TimeUnitunit)ScheduledFuture?

Runnablecommand
longdelay
longinterval
TimeUnitunit
ScheduledFuture?

scheduleWithFixedDelay(Runnablecommand, longdelay, longinterval, TimeUnitunit)ScheduledFuture?

Runnablecommand
longdelay
longinterval
TimeUnitunit
ScheduledFuture?

scheduleAt(Runnablecommand, Stringformat)ScheduledFuture?

Runnablecommand

The Runnable task to be scheduled for periodic execution.

Stringformat

A valid cron expression that defines the schedule for task execution. The cron format is parsed to calculate the next execution time.

ScheduledFuture?

A ScheduledFuture<?> representing the pending completion of the task. The ScheduledFuture can be used to cancel or check the status of the task.

Schedules a task to be executed periodically based on a cron expression.

This method uses a cron expression to determine the execution intervals for the given Runnable command. The task calculates the next execution time dynamically after each run using the provided cron format.

The method supports a general cron format with five fields (seconds, minutes, hours, day of month, month, and day of week) or six fields including seconds. Additionally, it includes special keywords such as L, W, R, ?, / to enhance scheduling flexibility.

Cron Expression Syntax

A cron expression is a string that represents a schedule using six fields (with seconds) or five fields (without seconds). Each field allows specifying ranges, lists, and special keywords to determine the precise schedule of the task. The following are the six fields:

  • Seconds: 0-59
  • Minutes: 0-59
  • Hours: 0-23
  • Day of Month: 1-31
  • Month: 1-12 or JAN-DEC (month names)
  • Day of Week: 0-7 (Sunday is both 0 and 7) or SUN-SAT (day names)

Supported Cron Special Characters

The following special characters are supported in cron expressions:

, (Comma)
Used to specify multiple values. For example, 0,15,30 * * * * * means the task will run at 0, 15, and 30 seconds.
- (Dash)
Specifies a range of values. For example, 10-20 * * * * * will run the task every second between 10 and 20 seconds.
/ (Slash)
Specifies intervals. For example, 0/10 * * * * * means the task will run every 10 seconds starting from 0 seconds.
L (Last)
Indicates the last day of the month or the last weekday of the month, depending on its context.
For the day-of-month field
L means the last day of the month (e.g., L * * * * runs on the last day of every month).
For the day-of-week field
L means the last occurrence of a specific weekday (e.g., 5L means the last Friday of the month).
W (Weekday)
Runs the task on the closest weekday (Monday to Friday) to the specified day. For example, 1W means the task will run on the closest weekday to the 1st of the month. If the 1st is a Saturday, the task runs on the following Monday (the 3rd), but it does not cross into the next month. Similarly, 31W in a month with fewer than 31 days will run on the last weekday of that month.
? (Any)
Used in the day-of-month or day-of-week field to specify that no specific value is set. It is typically used when you want to define one of these fields but not the other.
# (Nth Weekday)
Specifies the Nth occurrence of a weekday in a given month. For example, 3#1 means the first Tuesday of the month.
R (Random)
This is a custom extension similar to Jenkins' H keyword. R is used to schedule tasks at random times based on the hash of the task. For example, 5-30R * * * * * will select a random second between 5 and 30 for each execution. This helps distribute task executions over time to avoid simultaneous task execution peaks. By scattering task execution times randomly, the risk of heavy load caused by multiple tasks running at the same moment is reduced, effectively distributing the load across time.

Examples

Some cron expression examples:

0 0 12 * * ?
Executes at 12:00 PM every day.
0 15 10 * * ?
Executes at 10:15 AM every day.
0 0/5 14 * * ?
Executes every 5 minutes starting at 2:00 PM.
0 0 10 ? * 2#1
Executes at 10:00 AM on the first Monday of every month.
0 0 1W * * ?
Executes on the nearest weekday to the 1st day of every month.
0 0 0 L * ?
Executes at midnight on the last day of every month.
0 0 0 LW * ?
Executes at midnight on the last weekday of every month.
0 0 12 15 JAN *
Executes at noon on January 15th every year.
0 0 12 ? * MON-FRI
Executes at noon on weekdays (Monday to Friday).
0 15 10 15 AUG-DEC * *
Executes at 10:15 AM on the 15th of every month from August to December.
0 0 8 1-7/2 * *
Executes at 8:00 AM on every second day between the 1st and 7th of each month.
0 30 9 1,15,30 * *
Executes at 9:30 AM on the 1st, 15th, and 30th of every month.
0 0 10 5-10 * MON-WED
Executes at 10:00 AM between the 5th and 10th of every month, but only if the day is a Monday, Tuesday, or Wednesday.
0 0/15 9-17 * * MON-FRI
Executes every 15 minutes between 9:00 AM and 5:00 PM on weekdays (Monday to Friday).
5-10R * * * * *
Executes at a random second between 5 and 10 every minute.

scheduleAt(Runnablecommand, Stringformat, ZoneIdid)ScheduledFuture?

Runnablecommand

The Runnable task to be scheduled for periodic execution.

Stringformat

A valid cron expression that defines the schedule for task execution. The cron format is parsed to calculate the next execution time.

ZoneIdid

The time zone.

ScheduledFuture?

A ScheduledFuture<?> representing the pending completion of the task. The ScheduledFuture can be used to cancel or check the status of the task.

Schedules the task using the specified time zone. For more details, see #scheduleAt(Runnable, String).

shutdown()void

shutdownNow()ListRunnable

ListRunnable

awaitTermination(longtime, TimeUnitunit)boolean

longtime
TimeUnitunit
boolean
InterruptedException

isShutdown()boolean

boolean

isTerminated()boolean

boolean

execute(Runnablecommand)void

Runnablecommand

newTaskFor(CallableTcallable)RunnableFutureT

T
CallableTcallable
RunnableFutureT

newTaskFor(Runnablerunnable, Tvalue)RunnableFutureT

T
Runnablerunnable
Tvalue
RunnableFutureT