java schedule(task, 500, MILLISECONDS) 说明
如果你使用 scheduler.schedule(this, nextDelay, TimeUnit.MILLISECONDS) 这种方式,一定会等上一个任务执行完成后,再延迟 nextDelay 毫秒才调度下一次任务。
关键点
-
schedule()是单次调度,每次执行完成后才会安排下一次。 -
不会重叠执行,因为
ScheduledExecutorService默认是单线程的(除非你手动用多线程池)。 -
如果任务执行时间超过
nextDelay(如 500ms):-
任务完成后,才会计算
nextDelay并安排下一次。 -
实际间隔 = 任务执行时间 + nextDelay(例如:任务耗时 600ms,
nextDelay=500ms→ 实际间隔 1100ms)。
private void startLoopingExecution() { scheduler = Executors.newSingleThreadScheduledExecutor(); // 单线程 Runnable task = new Runnable() { @Override public void run() { long startTime = System.currentTimeMillis(); System.out.println("任务开始: " + DateTimeUtils.getCurrentTimeSSS()); try { // 模拟任务执行时间(假设有时快有时慢) long mockExecutionTime = Math.random() > 0.5 ? 300 : 800; // 300ms 或 800ms Thread.sleep(mockExecutionTime); } catch (Exception e) { e.printStackTrace(); } long elapsedTime = System.currentTimeMillis() - startTime; System.out.println("任务结束,耗时: " + elapsedTime + "ms"); // 固定 500ms 间隔(但实际间隔 = 本次执行时间 + 500ms) long nextDelay = 500; scheduler.schedule(this, nextDelay, TimeUnit.MILLISECONDS); } }; // 首次立即执行 scheduler.schedule(task, 0, TimeUnit.MILLISECONDS); }运行结果示例
任务开始: 14:30:00.000 任务结束,耗时: 300ms (下一次将在 500ms 后执行 → 14:30:00.800) 任务开始: 14:30:00.800 任务结束,耗时: 800ms (超过 500ms,但仍会等任务完成,再延迟 500ms → 14:30:02.100) 任务开始: 14:30:02.100 任务结束,耗时: 300ms (下一次 500ms 后 → 14:30:02.600) ...
结论:即使某次任务执行 800ms(超过 500ms),仍然会 等它执行完,再等 500ms 才执行下一次。
对比其他调度方式
调度方式 是否严格 500ms 间隔 是否可能重叠执行 适用场景 schedule(task, 500, MILLISECONDS)❌ 不严格(实际间隔 = 任务时间 + 500ms) ❌ 不会重叠 需要避免重叠,允许间隔波动 scheduleAtFixedRate(task, 0, 500, MILLISECONDS)✅ 严格(尽量按 500ms 间隔) ✅ 可能重叠 需要固定频率,任务必须短于间隔 scheduleWithFixedDelay(task, 0, 500, MILLISECONDS)❌ 不严格(实际间隔 = 任务时间 + 500ms) ❌ 不会重叠 类似手动 schedule(),但更简洁
如何选择?
-
如果不允许重叠,且可以接受间隔波动 → 用
schedule()(手动调度)或scheduleWithFixedDelay()。 -
如果必须严格 500ms 触发(即使任务堆积) → 用
scheduleAtFixedRate()(但要确保任务不会长时间阻塞)。 -
如果想动态调整间隔(如任务超时后缩短延迟)→ 手动
schedule()是唯一选择。
你的场景(交易系统)建议 用手动
schedule(),因为:-
避免重叠执行(防止并发问题)。
-
可以监控任务耗时,如果超过 500ms 可以报警或优化。
-
更灵活,可以动态调整
nextDelay。
-
浙公网安备 33010602011771号