不推荐在生产环境直接使用Executors.newFixedThreadPool,因其底层采用无界LinkedBlockingQueue,任务积压易导致内存溢出;应手动构建ThreadPoolExecutor,使用有界队列、自定义拒绝策略和线程工厂。

直接用 Executors.newFixedThreadPool(5) 就能创建一个固定 5 个线程的线程池,但要注意它底层用的是无界队列,任务积压时可能引发内存溢出,不推荐在生产环境直接使用。
newFixedThreadPool 的基本用法
这是最简单的创建方式,传入线程数量即可:
-
ExecutorService pool = Executors.newFixedThreadPool(3);—— 创建含 3 个核心线程、无界LinkedBlockingQueue的线程池 - 所有任务提交后由这 3 个线程轮流执行,空闲线程会一直存活(默认不超时)
- 即使没有任务,线程也不会自动销毁,适合长期稳定运行的场景
它背后的实际构造逻辑
这个工厂方法本质是调用了 ThreadPoolExecutor 的全参构造器:
- corePoolSize = maximumPoolSize = 指定数值(比如 3)
- keepAliveTime = 0L,所以空闲线程不会被回收
- workQueue = new LinkedBlockingQueue<Runnable>() —— 容量为
Integer.MAX_VALUE,即无界 - 拒绝策略是
AbortPolicy(抛出RejectedExecutionException)
为什么生产环境建议避免直接用它
关键风险来自无界队列:
立即学习“Java免费学习笔记(深入)”;
- 如果任务提交速度远大于执行速度(比如下游接口变慢),队列会无限堆积,最终 OOM
- 无法控制最大并发压力,拒绝策略只有在队列满+线程数达上限时才触发,而这里队列永远不会满
- 缺少线程名称自定义、监控钩子(如
beforeExecute)、饱和策略灵活替换等能力
更稳妥的替代写法
手动构建 ThreadPoolExecutor,显式控制关键参数:
- 用有界队列,比如
new ArrayBlockingQueue<Runnable>(100) - 设置合理的拒绝策略,例如
new ThreadPoolExecutor.CallerRunsPolicy() - 指定线程工厂,便于日志追踪:
new ThreadFactoryBuilder().setNameFormat("my-pool-%d").build() - 示例:new ThreadPoolExecutor(3, 3, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(100), factory, new CallerRunsPolicy())


















