Appearance
调度器(任务调度)
概述
Bngeuit 提供内置的任务调度器,支持同步和异步两种任务模式:
- 同步任务(
runSync):在专用单线程scheduler-sync上串行执行,任务之间天然线程安全 - 异步任务(
runAsync):在线程池scheduler-async(4 线程)中并发执行,适合 I/O 密集型操作
所有延迟/周期参数单位为毫秒。
快速上手
获取调度器
java
import cn.org.bukkit.bngeuit.Bngeuit;
import cn.org.bukkit.bngeuit.scheduler.BngeuitScheduler;
BngeuitScheduler scheduler = Bngeuit.getScheduler();立即执行
java
// 同步任务(与事件处理串行,线程安全)
scheduler.runSync(plugin, () -> {
// 直接操作游戏状态,无需加锁
System.out.println("同步执行");
});
// 异步任务(线程池并发)
scheduler.runAsync(plugin, () -> {
// 适合网络请求、文件 I/O 等
String result = httpGet("https://api.example.com/data");
});延迟执行
java
// 5 秒后同步执行
scheduler.runSyncLater(plugin, () -> {
Bngeuit.sendGroupText(groupOpenid, 1, "延迟消息");
}, 5000);
// 3 秒后异步执行
scheduler.runAsyncLater(plugin, () -> {
// 异步 I/O 操作
}, 3000);定时任务
java
// 每 60 秒执行一次(首次延迟 10 秒)
scheduler.runSyncTimer(plugin, () -> {
Bngeuit.sendGroupText(groupOpenid, 1, "定时消息");
}, 10000, 60000);
// 每 5 分钟异步轮询
scheduler.runAsyncTimer(plugin, () -> {
checkAndProcessQueue();
}, 0, 300000);取消任务
java
import cn.org.bukkit.bngeuit.scheduler.BngeuitTask;
// 保存任务句柄
BngeuitTask task = scheduler.runSyncTimer(plugin, () -> { ... }, 0, 60000);
// 取消单个任务
task.cancel();
// 或通过 ID 取消
scheduler.cancel(task.getTaskId());
// 取消插件的所有任务
scheduler.cancelTasks(plugin);查询任务
java
import java.util.List;
List<BngeuitTask> tasks = scheduler.getActiveTasks(plugin);
for (BngeuitTask t : tasks) {
System.out.printf("任务 #%d [%s] 已取消: %s%n",
t.getTaskId(), t.isSync() ? "同步" : "异步", t.isCancelled());
}API 参考
BngeuitScheduler
任务调度器接口。
任务提交
| 方法 | 说明 |
|---|---|
runSync(owner, task) | 立即同步执行 |
runSyncLater(owner, task, delayMs) | 延迟同步执行 |
runSyncTimer(owner, task, delayMs, periodMs) | 定时同步执行 |
runAsync(owner, task) | 立即异步执行 |
runAsyncLater(owner, task, delayMs) | 延迟异步执行 |
runAsyncTimer(owner, task, delayMs, periodMs) | 定时异步执行 |
参数说明:
owner:提交任务的插件(null表示系统任务)task:要执行的RunnabledelayMs:首次执行延迟(毫秒)periodMs:重复间隔(毫秒)
任务管理
| 方法 | 说明 |
|---|---|
cancel(taskId) | 按 ID 取消任务 |
cancelTasks(plugin) | 取消指定插件的所有任务(插件卸载时自动调用) |
getActiveTasks(plugin) | 查询指定插件的活跃任务列表 |
shutdown() | 关闭调度器(取消所有任务,关闭线程池) |
BngeuitTask
任务句柄接口。
| 方法 | 返回类型 | 说明 |
|---|---|---|
getTaskId() | int | 全局唯一任务 ID |
getOwner() | Plugin | 提交任务的插件(系统任务为 null) |
isSync() | boolean | 是否为同步任务 |
isCancelled() | boolean | 是否已取消或已完成 |
cancel() | void | 取消任务(不会中断正在执行的任务) |
同步 vs 异步
| 特性 | 同步任务 | 异步任务 |
|---|---|---|
| 执行线程 | 专用单线程 scheduler-sync 串行 | 线程池 scheduler-async(4 线程)并发 |
| 线程安全 | 任务之间天然串行安全 | 需自行处理同步 |
| 适用场景 | 需要顺序执行的定时任务 | 网络请求、文件 I/O |
| 阻塞影响 | 阻塞后续 sync 任务 | 不影响 sync 线程 |
注意
同步任务在独立的 scheduler-sync 线程上执行,与事件处理线程不同。但 sync 任务之间是串行的,长时间运行的 sync 任务会阻塞后续 sync 任务。与事件处理线程之间仍需注意并发安全。
插件卸载
插件卸载时,框架自动调用 cancelTasks(plugin) 清理该插件的所有任务。无需手动清理。
系统任务(owner == null)不受插件卸载影响。
完整示例
java
import cn.org.bukkit.bngeuit.Bngeuit;
import cn.org.bukkit.bngeuit.scheduler.*;
import cn.org.bukkit.bngeuit.event.SubscribeEvent;
import cn.org.bukkit.bngeuit.event.receive.GroupAtMessageEvent;
public class SchedulerExample {
private BngeuitTask heartbeatTask;
// 启动心跳定时任务
public void startHeartbeat(Plugin plugin, String groupOpenid) {
BngeuitScheduler scheduler = Bngeuit.getScheduler();
heartbeatTask = scheduler.runSyncTimer(plugin, () -> {
Bngeuit.sendGroupText(groupOpenid, 1, "机器人在线 ✓");
}, 0, 300000); // 每 5 分钟
}
// 停止心跳
public void stopHeartbeat() {
if (heartbeatTask != null) {
heartbeatTask.cancel();
}
}
// 异步请求示例
@SubscribeEvent
public void onCommand(GroupAtMessageEvent e) {
Plugin plugin = ...; // 获取当前插件
BngeuitScheduler scheduler = Bngeuit.getScheduler();
// 异步获取数据,完成后直接发送消息
scheduler.runAsync(plugin, () -> {
String data = fetchDataFromAPI();
// API 方法本身是线程安全的,无需切回 sync 线程
Bngeuit.replyGroupText(e.getGroupOpenid(), e.getId(), 1, data);
});
}
}