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

Java如何实现仅执行最新任务的ExecutorService?有哪些可行方案?

JDK 没有内置完全匹配该需求的 ExecutorService 实现,你可以基于现有线程池类自行扩展,也可以选择更适配场景的第三方工具实现。

自行实现核心思路
  • 因为同一时间仅需执行最新的一个任务,所以线程池配置为核心线程数、最大线程数均为1,避免多任务并行
  • 内部维护当前正在运行的任务的Future引用,新任务提交时先调用cancel(true)中断旧任务,再提交新任务并更新引用
  • 任务队列选择SynchronousQueue(不堆积待处理任务),兜底拒绝策略选择DiscardOldestPolicy避免提交失败
实现注意事项
  • 你提交的业务任务必须响应线程中断:要么正确处理InterruptedException,要么在任务执行的合适位置主动检查Thread.currentThread().isInterrupted()状态,否则中断逻辑不会生效,旧任务仍然会继续运行
  • 旧任务被中断抛出的异常建议在任务内部捕获处理,避免异常抛到线程池的未捕获异常处理器
最简实现代码
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;

public class LatestFirstExecutor extends ThreadPoolExecutor {
    private final AtomicReference<Future<?>> runningTask = new AtomicReference<>();

    public LatestFirstExecutor() {
        super(1, 1, 0L, TimeUnit.MILLISECONDS,
                new SynchronousQueue<>(),
                new ThreadPoolExecutor.DiscardOldestPolicy());
    }

    @Override
    public <T> Future<T> submit(Callable<T> task) {
        // 取消并清除旧任务
        Future<?> prev = runningTask.getAndSet(null);
        if (prev != null && !prev.isDone()) {
            prev.cancel(true);
        }
        // 提交新任务并更新引用
        Future<T> newTask = super.submit(task);
        runningTask.set(newTask);
        return newTask;
    }

    @Override
    public Future<?> submit(Runnable task) {
        return submit(Executors.callable(task));
    }
}
其他适配方案

如果你已经在使用响应式技术栈,不需要自己封装线程池:

  • RxJava 的 switchMap 操作符天生支持该逻辑:上游下发新事件时,会自动取消前一个事件对应的异步任务,直接执行最新事件的处理逻辑
  • Project Reactor 的 switchMap 操作符也可以实现同等效果,适合响应式项目使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 02:06:04