Java Timer暂停需求:待myLongRunningTask执行完成后再恢复定时
解决方案思路
你的需求完全可行,以下是两种实用实现思路:
方案一:改用ScheduledExecutorService(推荐)
Java原生Timer的固定周期调度是以上一次任务开始时间计算下一次触发点,很容易出现任务重叠或堆积的问题。而ScheduledExecutorService提供的scheduleWithFixedDelay方法,正好是以上一次任务执行完成时间为起点,等待指定延迟后再触发下一次,完美匹配你的需求。
代码示例:
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); Runnable task = () -> { myLongRunningTask(); }; // 首次延迟2秒执行,之后每次任务完成后等待5秒再执行 executor.scheduleWithFixedDelay(task, 2, 5, TimeUnit.SECONDS);
如果需要手动控制暂停/恢复,可以加一个开关变量:
AtomicBoolean isPaused = new AtomicBoolean(false); Runnable task = () -> { if (isPaused.get()) { return; } myLongRunningTask(); }; // 暂停:isPaused.set(true) // 恢复:isPaused.set(false)
方案二:基于原Timer改造(兼容原有代码)
如果一定要保留Timer,可以放弃固定周期调度,改为在任务执行完成后手动重新调度下一次任务。这样只有当前任务执行完毕,才会安排下一次触发,避免重叠。
代码示例:
Timer timer = new Timer(); TimerTask timerTask = new TimerTask() { @Override public void run() { try { myLongRunningTask(); } finally { // 任务执行完成后,5秒后调度下一次 timer.schedule(this, 5 * 1000); } } }; // 首次延迟2秒执行 timer.schedule(timerTask, 2 * 1000);
如果需要暂停功能,可以加一个volatile变量做控制:
volatile boolean isPaused = false; TimerTask timerTask = new TimerTask() { @Override public void run() { if (isPaused) { // 暂停时每隔1秒检查一次,可根据需求调整间隔 timer.schedule(this, 1000); return; } try { myLongRunningTask(); } finally { timer.schedule(this, 5 * 1000); } } };
内容的提问来源于stack exchange,提问作者Mitu
相关产品推荐
相关产品推荐

