一、线程池的执行流程
- 提交一个新线程任务
- 若线程池中不存在空闲线程,则判断当前“存活的线程数”是否小于核心线程数corePoolsize。
- 如果小于核心线程数 corePoolsize ,线程池会创建一个新线程(核心线程)去处理新线程任务;
- 如果大于核心线程数 corePoolsize ,线程池会检查工作队列;
- 如果工作队列未满,则将该线程任务放入工作队列进行等待。线程池中如果出现空闲线程,将从工作队列中按照FIFO的规则取出1个线程任务并分配执行;
- 如果工作队列已满,则判断线程数是否达到最大线程数 maximumPoolsize ;
- 如果当前“存活线程数”没有达到最大线程数 maximumPoolsize ,则创建一个新线程(非核心线程)执行新线程任务
- 如果当前“存活线程数”已经达到最大线程数 maximumPoolsize ,直接采用拒绝策略处理新线程任务;
二、线程池配置参数
1. FixedThreadPool
- 核心线程数 (
nThreads
): 线程池中线程的固定数量。 - 最大线程数: 始终与核心线程数相同,因为它是固定的。
- 任务队列: 采用无界队列(如
LinkedBlockingQueue
),可以排队等待执行的任务。
2. CachedThreadPool
- 核心线程数: 不固定,线程池会根据需求动态创建线程。
- 最大线程数: 理论上没有限制,线程数可根据系统资源自动调整。
- 空闲线程回收时间: 超过60秒未使用的线程会被回收。
3. ScheduledThreadPool
- 核心线程数 (
corePoolSize
): 线程池中保持的线程数量。 - 最大线程数: 理论上没有限制,具体取决于系统资源。
- 任务调度策略: 支持定时和周期性任务的执行。
4. SingleThreadExecutor
- 核心线程数: 1,确保任务按顺序执行。
- 最大线程数: 始终为1。
- 任务队列: 通常使用无界队列。
5. 自定义线程池
如果需要更细粒度的控制,可以使用 ThreadPoolExecutor
类自定义线程池。常用的参数包括:
- 核心线程数 (
corePoolSize
): 线程池中的基本线程数量,核心线程创建后不会被回收,大于核心线程数的线程,在空闲时间超过keepAliveTime后会被回收。
- 在创建了线程池后,默认情况下,线程池中并没有任何线程,当调用 execute()方法添加一个任务时,如果正在运行的线程数量小于 corePoolsize ,则马上创建新线程并运行这个任务。
- IO密集计算:由于 I/0设备的速度相对于 CPU 来说都很慢,所以大部分情况下, I/O 操作执行的时间相对于 CPU 计算来说都非常长,这种场景我们一般都称为 I/O 密集型计算。最佳线程数= CPU 核数*[1+(I/0 耗时/CPU 耗时)]。
- CPU密集型: CPU 密集型计算大部分场景下都是纯CPU 计算,多线程主要目的是提升 CPU 利用率,最佳线程数=“CPU 核心数 +1”。这样的话,当线程因为偶尔的内存页失效或其他原因导致阻塞时,这个额外的线程可以临时替补,从而保证 CPU的利用率。
- 最大线程数 (
maximumPoolSize
): 线程池能容纳的最大线程数量,线程池允许创建的最大线程数量(包含核心线程数量) - 线程存活时间 (
keepAliveTime
): 非核心线程存活时间,超过核心线程数的空闲线程在被回收前保持活动的时间。
- 当线程池中的线程数大于corePoolsize 时,如果一个线程空闲的时间达到 keepAliveTime,则会被回收,直到线程池中的线程数不超过 corePoolsize。
- 如果设置 allowCoreThreadTime0ut = true ,在线程池中的线程数不大于 corePoolsize 时,keepAliveTime 参数也会起作用,直到线程池中的线程数为0
- 时间单位 (Time
Unit
): 存活时间的时间单位(如TimeUnit.SECONDS
),参数keepAliveTime的时间单位
。 - 阻塞工作队列(BlockingQueue): 用于存储等待执行的任务,常用的有
LinkedBlockingQueue
和ArrayBlockingQueue
。 - 线程工厂 (
ThreadFactory
): 用于创建新线程的工厂。 - 拒绝策略 (RejectExecutionH
andler
): 当线程池和队列满,并且工作队列达到已满时,提交的任务,将使用拒绝策略,常用的有:AbortPolicy
: 默认策略,直接抛出RejectedexecutionException异常。CallerRunsPolicy
: 由调用者线程执行任务。DiscardPolicy
: 直接丢弃任务。DiscardOldestPolicy
: 丢弃队列中最旧的任务。