Java如何实现由fire方法触发首次执行的固定间隔定时任务调度方法
方案可行性结论
你提出的用列表存储调度任务、fire方法触发执行后更新下次调度时间的思路完全可行,只需调整少量细节即可满足需求,不需要执行完就把任务移出列表再重新添加,直接更新任务的下次触发时间即可,效率更高。
核心实现逻辑
任务存储结构
每个调度任务需要包装三个核心属性:
- 执行间隔时间
- 待执行的Runnable任务
- 下次触发的时间阈值(初始状态设为null,代表还未首次触发)
方法实现逻辑
scheduleEvery 方法
调用时将传入的间隔时间和Runnable包装成任务对象,存入线程安全的任务列表,同时返回ScheduledTask实例用于后续任务取消操作。
fire 方法
传入当前时间戳后遍历任务列表,对每个任务做如下判断:
- 如果任务已经被标记为取消,直接从列表移除
- 如果是首次触发(下次触发时间为null),判断当前时间是否大于等于任务的初始触发阈值,满足就执行任务
- 如果已经触发过,判断当前时间是否大于等于上次设置的下次触发时间,满足就执行任务
- 任务执行完成后,将下次触发时间更新为
当前时间 + 执行间隔
注意事项
- 线程安全:如果
scheduleEvery和fire会被多线程调用,需要使用线程安全的列表实现比如CopyOnWriteArrayList,或者操作列表时加锁,避免并发修改异常 - 异常处理:任务执行需要包裹
try-catch,避免单个任务抛出异常导致整个fire流程中断,其余任务无法正常调度 - 取消逻辑:返回的ScheduledTask可以实现cancel方法,标记任务为取消状态,下次fire时自动清理
核心代码示例
// 自定义ScheduledTask接口 public interface ScheduledTask { void cancel(); } // 调度器实现 public class PassiveScheduler { // 任务包装类 private static class TaskHolder { final long interval; final Runnable task; Long nextFireTime; boolean isCanceled; TaskHolder(long interval, Runnable task) { this.interval = interval; this.task = task; this.nextFireTime = null; this.isCanceled = false; } } private final List<TaskHolder> taskList = new CopyOnWriteArrayList<>(); // 初始触发阈值,对应你示例中的time=2001 private final long initTriggerThreshold; public PassiveScheduler(long initTriggerThreshold) { this.initTriggerThreshold = initTriggerThreshold; } public ScheduledTask scheduleEvery(long time, Runnable task) { TaskHolder holder = new TaskHolder(time, task); taskList.add(holder); return () -> holder.isCanceled = true; } public void fire(long currentTime) { for (TaskHolder holder : taskList) { if (holder.isCanceled) { taskList.remove(holder); continue; } boolean needRun = false; if (holder.nextFireTime == null) { needRun = currentTime >= initTriggerThreshold; } else { needRun = currentTime >= holder.nextFireTime; } if (needRun) { try { holder.task.run(); } catch (Exception e) { // 可自行替换为日志打印 e.printStackTrace(); } holder.nextFireTime = currentTime + holder.interval; } } } }
以上实现完全匹配你给出的运行规则示例。
内容的提问来源于stack exchange,提问作者Celine
相关产品推荐
相关产品推荐

