ExecutorService是Java中管理线程池的核心接口,通过Executors工厂类可创建固定、缓存、单线程和定时线程池;2. 任务可通过execute提交无返回值任务,或submit提交有返回值任务并获取Future结果;3. 线程池需调用shutdown或shutdownNow显式关闭,推荐结合awaitTermination确保优雅关闭;4. 生产环境建议直接使用ThreadPoolExecutor以精确控制队列和拒绝策略,避免资源耗尽问题。

在Java中,ExecutorService 是并发编程中管理线程池的核心接口,它简化了多线程任务的提交和执行,避免手动创建和管理线程。通过使用线程池,可以提升性能、控制资源消耗,并提高程序的可维护性。
创建线程池
Java通过 Executors 工厂类提供几种常用的线程池实现:
- Executors.newFixedThreadPool(n):创建一个固定大小的线程池,最多有n个线程同时运行。
- Executors.newCachedThreadPool():创建一个可缓存的线程池,线程数根据任务动态调整,空闲线程会在60秒后被回收。
- Executors.newSingleThreadExecutor():单线程的线程池,保证任务按顺序执行。
- Executors.newScheduledThreadPool(n):支持定时或周期性任务执行的线程池。
示例:创建一个包含4个线程的线程池
ExecutorService executor = Executors.newFixedThreadPool(4);
提交任务
可以通过两种方式向线程池提交任务:
立即学习“Java免费学习笔记(深入)”;
- execute(Runnable):用于提交无返回值的任务。
- submit(Runnable 或 Callable):返回一个 Future 对象,可用于获取任务执行结果或检查执行状态。
示例代码:
executor.execute(() -> { System.out.println("任务正在执行,线程名:" + Thread.currentThread().getName()); }); Future<Integer> future = executor.submit(() -> { return 42; }); try { Integer result = future.get(); // 获取结果,会阻塞直到完成 System.out.println("任务返回值:" + result); } catch (Exception e) { e.printStackTrace(); }
关闭线程池
使用完线程池后必须显式关闭,否则jvm可能无法退出。
- shutdown():停止接收新任务,等待已提交的任务执行完毕。
- shutdownNow():尝试立即停止所有正在执行的任务,返回未执行的任务列表。
推荐做法:
executor.shutdown(); try { if (!executor.awaitTermination(60, TimeUnit.SECONDS)) { executor.shutdownNow(); // 超时后强制关闭 } } catch (InterruptedException e) { executor.shutdownNow(); Thread.currentThread().interrupt(); }
实际使用建议
虽然 Executors 提供了便捷的工厂方法,但在生产环境中更推荐直接使用 ThreadPoolExecutor 构造函数,以便更精确地控制核心参数,如队列容量、拒绝策略等,防止资源耗尽。
常见问题如 newFixedThreadPool 使用无界队列,可能导致内存溢出,应结合具体场景选择合适的线程池类型和配置。
基本上就这些,掌握 ExecutorService 的创建、任务提交和关闭流程,就能有效管理线程资源,写出更健壮的并发程序。


