线程池ThreadPoolExecutor源码解析
Posted 松然聊技术
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程池ThreadPoolExecutor源码解析相关的知识,希望对你有一定的参考价值。
张强,16年加入京东,目前就职于京东商城京麦平台组,从事京东对外开放平台和服务于第三方入驻商家的相关工作,开源爱好者,对常用开源框架如Spring、Mybatis、Dubbo等有源码级别的了解,热衷于研究各种技术,致力于成为一名有腔调的工程师
正文
我们在使用线程池的时候,可以使用Executors工厂类来创建线程池,或者是直接使用构造方法创建,我们首先来看一下ThreadPoolExecutor的构造方法: ThreadPoolExecutor:
我们来解释一下构造方法中这些参数的作用:
corePoolSize:当我们向线程池中提交任务时,线程池会创建一个新线程来执行任务,直到当前线程数等于corePoolSize,这时后面再次提交的任务会被保存到阻塞队列中,等待被执行。如果执行了线程池的prestartAllCoreThreads()方法,线程池会提前创建并启动所有核心线程
maximumPoolSize:线程池线程数量的最大上限,如果当前阻塞队列满了,且继续提交任务,则创建新的线程执行任务,前提是当前线程数小于maximumPoolSize
keepAliveTime:线程空闲时的存活时间,即当线程没有任务执行时,继续存活的时间,默认情况下,该参数只在线程数大于corePoolSize时才有用
unit:是keepAliveTime的时间单位
workQueue:任务存储的队列,用来保存等待被执行的任务的阻塞队列,在JDK中提供了如下阻塞队列:
ArrayBlockingQueue:基于数组结构的有界阻塞队列,按FIFO排序任务
LinkedBlockingQuene:基于链表结构的阻塞队列,按FIFO排序任务,吞吐量通常要高于ArrayBlockingQuene
SynchronousQuene:一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQuene
priorityBlockingQuene:具有优先级的无界阻塞队列
threadFactory:创建线程的工厂,默认为Executors.DefaultThreadFactory,里面定义了线程计数,并且给生产的线程命名(pool-线程池号-thread-线程号),可以自定义,实现ThreadFactory重写newThread方法
handler:饱和策略,可以自定义,实现RejectedExecutionHandler重写rejectedExecution方法
AbortPolicy:默认饱和策略,直接抛出一个RejectedExecutionException异常,让调用者自己处理
DiscardPolicy:后续的任务都抛弃掉
DiscardOldestPolicy:会将等待队列里最旧的任务踢走,让新任务得以执行
CallerRunsPolicy:它既不抛弃新任务,也不抛弃旧任务,而是直接在当前线程运行这个任务,当前线程一般就是主线程,主线程运行任务,有可能会阻塞,推荐少用
下面我们来看一下我们为线程池提交任务时使用的execute方法: ThreadPoolExecutor:
这里翻译一下方法中给出的注释:
分三步进行:
如果少于corePoolSize线程正在运行,尝试使用给定命令作为第一个任务启动一个新线程,对addWorker的调用以原子方式检查runState和workerCount,返回false防止错误报警在不应该增加时增加线程
如果任务可以成功排队,那么我们仍然需要二次检查是否应该添加一个线程(因为现有的线程自上次检查以来已经死掉)或者自进入此方法后关闭了该线程。 所以我们重新检查状态,如果有必要的话回滚队列,如果没有的话,就开始一个新的线程
如果我们不能排队任务,那么我们尝试添加一个新线程。 如果失败,我们知道我们已关闭或饱和,因此拒绝任务
我们用一张图来表示这个过程,这张图是网上找的,可以很清晰的表示这个过程:
方法里我们看到获取线程池的运行状态和线程数量都和一个叫做ctl的变量有关,我们来分析一下这个变量 ......
------> 内容过长,请点击阅读原文
以上是关于线程池ThreadPoolExecutor源码解析的主要内容,如果未能解决你的问题,请参考以下文章
Java Executor源码解析—ThreadPoolExecutor线程池其他方法的源码
线程池技术之:ThreadPoolExecutor 源码解析
Java Executor源码解析—ThreadPoolExecutor线程池execute核心方法源码一万字
线程池ThreadPoolExecutor——Worker源码解析
Java Executor源码解析—ThreadPoolExecutor线程池submit方法以及FutureTask源码一万字