ExecutorService 是 Java 线程池核心接口,提供 submit(Runnable/Callable/Runnable+result)、invokeAll/invokeAny、shutdown/awaitTermination/shutdownNow 等方法,支持任务提交、批量执行与生命周期控制;推荐手动构造 ThreadPoolExecutor 而非 Executors 工厂类。

Java 中的 ExecutorService 是线程池任务管理的核心接口,它把“任务”和“执行者”解耦,让你专注业务逻辑,不用操心线程创建、销毁、复用等底层细节。它不是具体实现,而是一套标准契约,真正干活的是 ThreadPoolExecutor、ScheduledThreadPoolExecutor 等实现类。
ExecutorService 的三种任务提交方式
提交任务是使用 ExecutorService 最频繁的操作,不同场景对应不同方法:
-
submit(Runnable task):提交无返回值任务,返回
Future<?>。适合日志记录、异步通知等不关心结果的场景。 -
submit(Callable<T> task):提交有返回值任务,返回
Future<T>。适合需要汇总计算结果的并发处理,比如批量查询用户信息后聚合统计。 - submit(Runnable task, T result):提交 Runnable,但指定一个预设返回值。适用于任务本身不产出数据,但调用方需要统一返回标识(如成功码、默认对象)的情况。
批量任务执行与结果获取
当需要并行处理多个独立任务并等待全部完成时,invokeAll() 和 invokeAny() 更高效:
-
invokeAll(Collection<? extends Callable<T>> tasks):阻塞直到所有任务完成,返回按任务顺序排列的
List<Future<T>>。可遍历每个 Future 获取结果或异常。 - invokeAny(Collection<? extends Callable<T>> tasks):只要任意一个任务成功返回,就立即返回其结果,其余未完成任务会被取消。适合“竞速型”场景,如多通道网络请求取最快响应。
线程池生命周期控制
不正确关闭线程池会导致资源泄漏或任务丢失。关键方法不是互斥的,而是配合使用:
立即学习“Java免费学习笔记(深入)”;
- shutdown():拒绝新任务,但允许已提交任务继续执行。这是推荐的优雅关闭方式。
- awaitTermination(long timeout, TimeUnit unit):配合 shutdown() 使用,等待所有已提交任务结束。超时后应考虑是否强制终止。
- shutdownNow():尝试中断所有正在运行的线程,并返回尚未执行的任务列表。适用于紧急退出或测试清理,但无法保证任务原子性。
常见线程池类型与选型建议
通过 Executors 工厂类 创建线程池快捷方便,但生产环境更推荐手动构造 ThreadPoolExecutor 以避免潜在风险:
- newFixedThreadPool(n):固定 n 个线程,适合负载稳定、需控并发量的场景(如订单处理)。注意其默认使用无界队列,高并发下易 OOM。
- newCachedThreadPool():空闲线程 60 秒回收,适合大量短时任务(如 RPC 响应处理)。但线程数无上限,突发流量可能耗尽系统资源。
- newSingleThreadExecutor():保证任务串行执行,适合需严格顺序的场景(如日志写入、状态机更新)。
-
newScheduledThreadPool(n):支持延迟和周期执行,是
Timer的线程安全替代方案。


















