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
相关产品推荐
相关产品推荐

