TaskKit Task Utilities
Introduction
A utility module combining tasks, time, delay listeners, timeout listeners, and more.
Usage scenarios
- Timeout handling tasks
- Timer simulation
- Task scheduling
- IO task handling
- Delayed tasks
Consumption of Single Task
Used for some IO tasks, or tasks that should not block business threads.
- code 3: execute task with CacheThreadPool.
- code 7: execute task with virtual threads.
public void execute() {
TaskKit.execute(() -> {
log.info("CacheThreadPool consumer task");
});
TaskKit.executeVirtual(() -> {
log.info("Virtual consumer task");
});
}
TaskListener Task Monitoring Callback Interface
TaskListener is a callback interface for time-related task monitoring.
Usage scenarios
One-time delayed tasks, task scheduling, lightweight controllable delayed tasks, lightweight periodic DB-write helpers, and other extension scenarios.
TaskListener provides several methods.
Only onUpdate is required; others can be overridden as needed.
| Method | Modifier | Description |
|---|---|---|
| onUpdate | Callback | |
| triggerUpdate | default | Whether to trigger onUpdate() callback |
| onException(Throwable) | default | Exception callback. If exceptions are thrown while running triggerUpdate() or onUpdate(), this method catches them. |
| getExecutor | default | Specify an executor for the above methods to avoid occupying business threads. |
Method description
- onUpdate: write business logic here.
- triggerUpdate:
trueexecutesonUpdate;falsedoes not. - onException: catches exceptions thrown by
triggerUpdateoronUpdate. Useful for unified handling and isolation so tasks do not affect each other. - getExecutor: specify an executor to consume the current task and avoid occupying default business threads.
@Slf4j
public class MyTaskListener implements TaskListener {
@Override
public void onUpdate() {
... your code
}
@Override
public boolean triggerUpdate() {
return true;
}
@Override
public void onException(Throwable e) {
log.error(e.getMessage(), e);
}
@Override
public Executor getExecutor() {
// return TaskKit.getCacheExecutor();
return TaskKit.getVirtualExecutor();
}
}
OnceTaskListener Timeout and Delay Handling Tasks
Timeout handling and delayed handling, executed only once. Suitable for tasks without IO operations.
| Type | Parameter Name | Description |
|---|---|---|
| OnceTaskListener | taskListener | Listener |
| long | delay | Delay time |
| TimeUnit | unit | Time unit |
Code description
- code 2: execute once, after 2 seconds.
- code 3: execute once, after 1 minute.
- code 4: execute once, after 500 milliseconds.
- code 15: execute once, after 1500 milliseconds; execute
onUpdateonly whentheTriggerUpdateistrue.
public void runOnce() {
TaskKit.runOnce(() -> log.info("2 Seconds"), 2, TimeUnit.SECONDS);
TaskKit.runOnce(() -> log.info("1 Minute"), 1, TimeUnit.MINUTES);
TaskKit.runOnce(() -> log.info("500 delayMilliseconds"), 500, TimeUnit.MILLISECONDS);
boolean theTriggerUpdate = RandomKit.randomBoolean();
TaskKit.runOnce(new OnceTaskListener() {
@Override
public void onUpdate() {
log.info("1500 delayMilliseconds");
}
@Override
public boolean triggerUpdate() {
return theTriggerUpdate;
}
}, 1500, TimeUnit.MILLISECONDS);
}
Comprehensive example exercise
This section uses a case to describe usage.
Business scenario:
Duration-based skill effects, or turn countdowns in board/card games such as Hearthstone-like games, Three Kingdoms Kill, Dou Dizhu, Mahjong, and similar games.
When it is a player's turn, the game UI usually shows a countdown. The player must finish within the time limit. A common approach is using a timer. If player action is completed in time, the timer must be cancelled.
The framework's
TaskKit.runOncecan simulate a timer. This usage can make business code clearer. By extendingOnceTaskListener, business requirements (such as timer cancellation) can be achieved, and this design better follows single responsibility.
In code, two classes are defined: Room and OperationTask.
- Room is the current room class, storing match and player-related information.
A
roundproperty is defined to record current round count (used to control whether timer executes). Whenever player operation completes,roundchanges (+1). - OperationTask is a timer-task listener class assisting business logic. Key logic is in
triggerUpdate. Only whenOperationTask.currentRoundequalsroom.rounddoesonUpdatetrigger. This approach does not require explicitly cancelling timers, but controls execution through business logic.
public void test() {
Room room = new Room();
// start next round
room.startNextRound();
// start next round, previous task will not execute
room.startNextRound();
}
record OperationTask(int currentRound, Room room) implements OnceTaskListener {
@Override
public void onUpdate() {
room.notice();
}
@Override
public boolean triggerUpdate() {
return currentRound == room.round.get();
}
}
class Room {
AtomicInteger round = new AtomicInteger(1);
long currentOperationPlayerId;
void notice() {
this.startNextRound();
}
void startNextRound() {
int currentRound = this.round.incrementAndGet();
this.currentOperationPlayerId = 100;
TaskKit.runOnce(new OperationTask(currentRound, this), 1, TimeUnit.SECONDS);
}
}
IntervalTaskListener Interval Execution and Task Scheduling
This method is mainly used to simulate ScheduledThreadPoolExecutor.
If tasks need interval execution (every N seconds/minutes/hours), this method can be used as a replacement.
Tasks can be consumed multiple times, execution can be controlled, and cancellation is supported.
| Type | Parameter Name | Description |
|---|---|---|
| IntervalTaskListener | taskListener | Task listener |
| long | tick | Tick interval; callback is invoked once per tick interval |
| TimeUnit | timeUnit | Tick time unit |
It is similar to OnceTaskListener, so details are not repeated.
Compared with OnceTaskListener, this interface adds isActive.
When isActive returns false, it is removed from the scheduler.
IntervalTaskListener supports:
- Task scheduling (interval and time unit)
- Task removal
- Task skip
- Custom executor
- code 2: invoke once every 2 seconds.
- code 3: invoke once every 30 minutes.
public void runInterval() {
TaskKit.runInterval(() -> log.info("tick 2 Seconds"), 2, TimeUnit.SECONDS);
TaskKit.runInterval(() -> log.info("tick 30 Minute"), 30, TimeUnit.MINUTES);
}
- code 12: returning
falsemeans inactive; current listener is removed from listener list.
public void runInterval() {
TaskKit.runInterval(new IntervalTaskListener() {
int hp = 2;
@Override
public void onUpdate() {
hp--;
}
@Override
public boolean isActive() {
return hp != 0;
}
}, 1, TimeUnit.SECONDS);
}
- code 12: execute
onUpdateonly when return value istrue.
public void runInterval() {
TaskKit.runInterval(new IntervalTaskListener() {
int hp;
@Override
public void onUpdate() {
// your code
}
@Override
public boolean triggerUpdate() {
hp++;
return hp % 2 == 0;
}
}, 1, TimeUnit.SECONDS);
}
- code 12: specify executor to execute
onUpdatecallback, avoiding blocking other tasks.
public void runInterval() {
ExecutorService executorService = TaskKit.getCacheExecutor();
TaskKit.runInterval(new IntervalTaskListener() {
@Override
public void onUpdate() {
// your DB code
}
@Override
public Executor getExecutor() {
return executorService;
}
}, 1, TimeUnit.SECONDS);
}
Summary
TaskKit provides multiple task-consumption modes:
executeseries: task consumed once.runOnceseries: task consumed once; supports delayed execution and cancellation.runIntervalseries: task consumed multiple times; execution can be controlled and cancellation is supported.