You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 05:58:26