当前位置:首页>java>Java 线程池超详细讲解(核心原理、七大参数、四种拒绝策略、常用线程池、面试全集)

Java 线程池超详细讲解(核心原理、七大参数、四种拒绝策略、常用线程池、面试全集)

  • 2026-10-10 14:46:24
Java 线程池超详细讲解(核心原理、七大参数、四种拒绝策略、常用线程池、面试全集)

一、什么是线程池?

线程池(ThreadPool)是 Java 用来统一管理、复用线程的工具。
传统多线程问题:
频繁 new Thread() 创建线程、销毁线程,开销极大
线程无限制创建,内存溢出、CPU 爆满
无法统一管理任务,混乱不可控
线程池核心思想:线程复用
提前创建若干线程,任务来了直接用,任务结束线程不销毁,等待下一个任务,避免频繁创建销毁。

二、为什么要用线程池?(五大优势)

降低资源消耗:复用线程,减少创建销毁开销
提高响应速度:任务无需等待线程创建,直接执行
统一管理线程:统一调度、监控、分配任务
控制并发数量:防止无限创建线程导致 OOM
提供丰富功能:延时执行、定时执行、拒绝策略

三、线程池七大核心参数(面试必考)

Java 真正的线程池 ThreadPoolExecutor 有7 大参数,是面试核心。
publicThreadPoolExecutor(int corePoolSize,      // 核心线程数int maximumPoolSize,   // 最大线程数long keepAliveTime,    // 空闲线程存活时间TimeUnit unit,         // 时间单位BlockingQueue workQueue, // 任务阻塞队列ThreadFactory threadFactory, // 线程工厂RejectedExecutionHandler handler // 拒绝策略)

参数详解

corePoolSize 核心线程数:常驻线程,永远不销毁(除非设置allowCoreThreadTimeOut)
maximumPoolSize 最大线程数:线程池能容纳的最大线程数量
keepAliveTime 空闲时间:非核心线程空闲多久自动销毁
unit:时间单位(秒、分、时)
workQueue 阻塞队列:任务满了之后,存入队列排队
threadFactory 线程工厂:负责创建线程、设置线程名称、优先级
handler 拒绝策略:队列和线程全部满了,新任务如何处理

四、线程池完整执行流程(最核心)

任务提交后,线程池执行顺序1-2-3-4 步:
判断核心线程数:如果当前运行线程数 < 核心线程数,新建核心线程执行任务
判断队列:核心线程已满,将任务加入阻塞队列排队
判断最大线程数:队列已满,新建非核心线程执行任务
触发拒绝策略:线程数达到最大值、队列也满,执行拒绝策略
口诀:先核心、再队列、再最大、最后拒绝

五、四种拒绝策略(面试必背)

1. AbortPolicy(默认)

直接抛出异常RejectedExecutionException,中断任务。

2. CallerRunsPolicy

谁提交的任务,谁自己跑(主线程执行),不抛弃、不报错。

3. DiscardPolicy

直接丢弃当前新任务,不报错、不执行。

4. DiscardOldestPolicy

丢弃队列中最旧的任务,加入当前新任务。

六、JDK 内置四种常用线程池

JDK 提供 Executors 工具类快速创建线程池,阿里巴巴规范禁止在项目中直接使用,但面试必须掌握。

1. newFixedThreadPool(固定线程池)

核心线程数=最大线程数,线程数量固定,适合长期稳定任务。
问题:队列无界,任务过多会OOM

2. newCachedThreadPool(缓存线程池)

线程无限多、空闲60秒回收,适合大量短时任务。
问题:线程无限创建,容易CPU 打满、OOM

3. newSingleThreadExecutor(单线程池)

只有一个线程,任务串行执行,适合顺序任务。

4. newScheduledThreadPool(定时线程池)

支持延迟执行、周期性定时任务,适合定时任务调度。

七、为什么阿里禁止使用 Executors?

FixedThreadPool、SingleThreadPool:队列无界,堆积任务导致 OOM
CachedThreadPool:线程数量无界,无限创建线程导致系统崩溃
企业规范:手动创建 ThreadPoolExecutor 自定义线程池

八、企业级自定义线程池(标准代码)

public class ThreadPoolConfig {// 核心线程数:CPU核心数private static final int CORE_SIZE = Runtime.getRuntime().availableProcessors();// 最大线程数private static final int MAX_SIZE = CORE_SIZE * 2;// 空闲时间private static final long KEEP_ALIVE = 10L;publicstatic ThreadPoolExecutor getThreadPool(){return new ThreadPoolExecutor(CORE_SIZE,MAX_SIZE,KEEP_ALIVE,TimeUnit.SECONDS,new ArrayBlockingQueue<>(100), // 有界队列Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy() // 不抛异常);}}

九、核心线程数如何设置?(面试标准答案)

1. CPU 密集型(计算多、IO少)

核心线程数 = CPU核心数 + 1
原因:充分利用CPU,避免线程切换浪费性能

2. IO 密集型(数据库、网络、文件读写)

核心线程数 = CPU核心数 * 2
原因:IO阻塞时,线程空闲,可以多开线程处理任务

十、线程池生命周期

RUNNING:运行中,接收新任务、处理排队任务
SHUTDOWN:不再接收新任务,继续执行已有任务
STOP:不接收新任务、中断正在执行的任务
TIDYING:所有任务结束,线程归零
TERMINATED:线程池彻底关闭

十一、面试满分总结(背诵版)

  1. 线程池作用:复用线程、减少开销、控制并发、防止OOM。
  2. 七大参数:核心线程数、最大线程数、空闲时间、时间单位、阻塞队列、线程工厂、拒绝策略。
  3. 执行流程:先核心线程、再队列、再非核心线程、最后拒绝策略。
  4. 四种拒绝策略:抛异常、主线程执行、丢弃任务、丢弃最旧任务。
  5. 开发规范:禁止使用Executors,手动自定义有界队列线程池,根据CPU/IO密集型合理设置线程数。

最新文章

随机文章