Java 开发的同学肯定使用过多线程,使用多线程那就肯定会用到线程池。而且个人认为线程池也是各大互联网公司在面试的时候比问的一个知识点。因此作为开发人员,必须了解线程池的原理以及具体参数的含义。
首先我们来了解下线程池的基本原理
- 第一步便是我们将我们的任务提交给线程池
- 如果线程池中有足够的线程或者线程数小于核心线程数,则直接执行任务或者创建一个新的线程来执行该任务。否则进入步骤 3
- 提交任务时,线程池中的空闲的线程数为 0 并且线程数等于核心线程数,则观察线程池中的任务队列是否已满,如果未满则将任务添加到任务队列,否则进入步骤 4
- 当任务队列已满时,就执行拒绝策略 (后续详解拒绝策略)
在大致了解了线程池的基本工作原理之后,我们再细看下线程池核心类 ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {// 省略具体的代码内容}
参数说明
参数 | 说明 |
---|---|
corePoolSize | 核心线程数 |
maximumPoolSize | 最大线程数,一般大于等于核心线程数 |
keepAliveTime | 线程存活时间 (针对最大线程数大于核心线程数时,非核心线程) |
unit | 存活时间单位,和线程存活时间配套使用 |
workQueue | 任务队列 |
threadFactory | 创建线程的工程 |
handler | 拒绝策略 |
拒绝策略有以下几种
拒绝策略 | 说明 |
---|---|
AbortPolicy | 为 java 线程池默认的阻塞策略,不执行此任务,而且直接抛出一个运行时异常。 |
DiscardOldestPolicy | 丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程) |
DiscardPolicy | 也是丢弃任务,但是不抛出异常 |
CallerRunsPolicy | 由调度线程处理该任务 |