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

如何使用ScheduledExecutorService取消当前正在运行的定时任务?

取消周期性调度任务的实现方案

你不需要关闭executor实例即可终止指定周期任务,核心实现是调用ScheduledFuture自带的cancel()方法,该操作只会终止当前任务的后续调度,完全不影响线程池内其他任务的运行。

由于lambda表达式定义时scheduledTask还未完成赋值,无法直接在内部引用该变量,你可以通过AtomicReference包装解决引用时序问题,参考实现如下:

import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.ScheduledFuture;

// 原子引用存储ScheduledFuture实例
AtomicReference<ScheduledFuture<?>> taskRef = new AtomicReference<>();
ScheduledFuture<?> scheduledTask = _executor.scheduleWithFixedDelay(() -> {
    try {
        // 注意原代码判断逻辑写反:条件不成立时执行取消逻辑
        if (!isValid()) {
            // 先执行自定义的任务关闭逻辑
            // Do tasks to close
            
            // 取消周期任务,参数false表示不中断当前正在运行的任务,待本次逻辑执行完后不再生成后续任务
            // 如果需要立刻中断当前任务的运行,可将参数改为true
            taskRef.get().cancel(false);
        }
    } catch (Throwable e) {
        log.fatal("Unexpected error..", e);
        // 异常场景也可选择取消任务,避免后续重复报错
        taskRef.get().cancel(false);
    }
}, 0L, 30, TimeUnit.SECONDS);
// 将初始化完成的Future存入原子引用
taskRef.set(scheduledTask);

cancel方法参数说明

  • cancel(false):仅取消后续的调度计划,当前正在执行的本次任务会正常跑完所有逻辑,适配你的业务场景
  • cancel(true):会向当前运行任务的线程发送中断信号,适合任务支持中断、需要立刻终止执行的场景

可选简化方案

如果不想引入原子引用,也可以在执行完关闭逻辑后主动抛出未捕获的RuntimeException,ScheduledExecutorService收到未捕获异常后会自动终止该任务的后续调度,也不会影响线程池的其他功能:

ScheduledFuture<?> scheduledTask = _executor.scheduleWithFixedDelay(() -> {
    try {
        if (!isValid()) {
            // Do tasks to close
            // 抛出异常终止后续调度
            throw new RuntimeException("校验不通过,终止周期任务");
        }
    } catch (RuntimeException e) {
        // 放行终止任务用的自定义异常
        throw e;
    } catch (Throwable e) {
        log.fatal("Unexpected error..", e);
        throw new RuntimeException("任务执行异常,终止周期调度", e);
    }
}, 0L, 30, TimeUnit.SECONDS);

内容的提问来源于stack exchange,提问作者Chillax

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 05:45:01