schedulewithfixeddelay 是在前一次任务执行结束后等待指定延迟再启动下一次任务的调度方式,确保串行执行、不重叠;其开始时间间隔等于任务耗时加延迟时间,适合资源独占场景。

scheduleWithFixedDelay 是 ScheduledExecutorService 提供的一种周期性任务调度方式,它在**前一次任务执行结束后,等待指定延迟时间,再启动下一次任务**。和 scheduleAtFixedRate 不同,它不关心任务耗时,只保证“上一次结束 → 延迟 → 下一次开始”这个节奏。
核心用法:创建并提交任务
你需要一个 ScheduledExecutorService 实例(通常用 Executors.newScheduledThreadPool(1) 创建),然后调用 scheduleWithFixedDelay 方法:
- 第一个参数:要执行的
Runnable或Callable任务 - 第二个参数:初始延迟(首次执行前等待多久)
- 第三个参数:固定延迟时间(每次执行完后等多久再执行下一次)
- 第四个参数:时间单位(如
TimeUnit.SECONDS)
示例代码:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleWithFixedDelay(() -> {
System.out.println("任务执行中,当前时间:" + new Date());
try {
Thread.sleep(2000); // 模拟耗时操作(比如网络请求、文件处理)
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, 1, 3, TimeUnit.SECONDS);
上面这段代码表示:1 秒后首次执行,之后每次执行完等 3 秒再执行下一次。即使任务本身耗时 2 秒,两次执行的**开始时间间隔仍是 ≈ 5 秒(2秒运行 + 3秒延迟)**,不会重叠或堆积。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
关键特点:延迟从任务结束算起
这是它和 scheduleAtFixedRate 的本质区别:
- 如果任务执行很快(比如 100ms),那两次执行的开始时间间隔 ≈ 延迟时间(如 3 秒)
- 如果任务执行很慢(比如 4 秒),那下一次会在它结束后的 3 秒才启动,实际间隔是 4+3=7 秒 —— 它不会并发执行,也不会跳过某次
- 适合对任务串行性、资源独占性要求高的场景(如数据库清理、本地缓存刷新)
如何停止任务
该方法返回一个 ScheduledFuture>,你可以用它来取消任务:
ScheduledFuture> future = scheduler.scheduleWithFixedDelay(...); // 后续某处想停止 future.cancel(true); // true 表示中断正在执行的任务线程
别忘了最后关闭线程池:
scheduler.shutdown();
try {
if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
scheduler.shutdownNow();
}
} catch (InterruptedException e) {
scheduler.shutdownNow();
Thread.currentThread().interrupt();
}
注意事项
- 任务抛出未捕获异常会导致该周期任务终止(后续不再执行),建议在
Runnable内加try-catch - 线程池大小要合理:单任务用 1 核心线程即可;多个独立延迟任务可适当增加,但避免过大
- 延迟时间为 0 是合法的,表示“上一次一结束就立刻执行下一次”,但需确保任务本身不阻塞或死循环
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










