摘要
文章介绍了ThreadPoolExecutor常用的7个参数,核心线程数、最大线程数、非核心线程的存活时间和时间单位、工作队列、线程工厂、拒绝策略,根据具体的应用场景,合理地定义这些参数是用好线程池的关键。最后也介绍了线程池整体的工作流程。
正文
一、线程池的核心组件
1、 核心线程数
核心线程是一直存活在线程池中的线程,即使他们是空闲的,他们也不会被线程池回收掉。正是因为核心线程数的存在,当有任务到达时不用再去创建新的线程,减少了任务的响应时间。
2、最大线程数
顾名思义,最大线程数是线程池中线程数量的上限。线程池中除了有核心线程外,还有非核心线程(工作线程),在任务量很大,单靠核心线程已经无法支撑时,工作线程就会被创建出来,用来分摊核心线程的压力,而最大线程数就等于核心线程数加上工作线程数。很容易知道,最大线程数指定了一个线程池可以承担的最大并发量。
3、存活时间和时间单位
存活时间指定了一个时间范围,当非核心线程处于空闲状态的时间超出存活时间时,线程池就会将非核心线程回收掉。
4、工作队列
工作队列是在任务执行前,用来存放任务的地方。很容易知道,工作队列让线程池拥有了应对集中式爆发式请求的能力。
5、线程工厂
指定创建线程的线程工厂,该线程池中的所有线程都由指定的线程工厂创建,默认为Executors.DefaultThreadFactory,DefaultThreadFactory创建的线程都存在于一个线程组中,都指定为NORMAL_PRIORITY优先级,且非守护线程。
6、拒绝策略
当线程池已经关闭或者线程池已经达到最大线程数并且工作队列已经满时,会触发拒绝策略。
4种拒绝策略
- ThreadPoolExecutor.AbortPolicy:默认的拒绝策略,直接抛出异常
- ThreadPoolExecutor.CallerRunsPolicy:用当前的线程去执行该任务,直接运行
- ThreadPoolExecutor.DiscardPolicy:直接丢弃该任务
- ThreadPoolExecutor.DiscardOldestPolicy:与DiscardPolicy不同,DiscardOldestPolicy是丢弃工作队列队首的任务
二、线程池的工作流程
线程池的工作流程
当一个请求任务到来时,线程池会按下面4步执行操作
- 核心线程有空闲:将任务交给核心线程执行
- 工作队列未满:将任务暂存到工作队列中,当有线程空闲时便弹出任务交给线程执行
- 未达到最大线程数:创建工作线程,提供线程池的并发能力
- 执行拒绝策略:按照指定的拒绝策略进行相应的操作