线程池源码解析_One:Executors.newFixedThreadPool(nthreads)

线程池源码解析_one:Executors.newFixedThreadPool(nthreads):

1、构造函数

传入参数:核心线程工作者数量

 

关键类:ThreadPoolExecutor

传参:corePoolSize核心工作者数量、maximumPoolSize最大工作者数量、keepAliveTime(在fixedThreadPool中无用)unit(在fixedThreadPool中无用)workQueue队列(当工作者数量超过预定的核心工作者数量时将新增的任务放入队列)

注:

a、工作者(Worker):新增的任务线程会放进此Worker类中,该Worker 也是一个Runnable线程,该Worker内部也会维护一个Thread实例, 调用thread实例的start方法,即执行该Worker线程,同时在Worker 的run方法中调用新增的任务的run方法

b、Worker存放在HashSet中

2、submit提交任务:

ThreadPoolExecutor-继承->AbstractExecutorService-实现->ExecutorService(接口)-继承->Executor(接口)

最终执行的是ThreadPoolExecutor中的execute()方法

查看该方法前需要了解表示线程的状态以及工作者数量的方式:

Ctl:该数值包含了线程池的状态(高三位表示)和工作者的数量(低29位表示),该类是院子操作,底层是Unsafe类cas操作

CtlOf():rs表示状态(RUNNING,SHUTDOWN,STOP,TIDYING,TERMINATED), wc表示工作者数量,通过|操作得到既包含状态又包含数量的数值

RunStateOf():将ctl值传入得到高三位数值,即可获知当前状态

WorkerCountOf():将ctl值传入得到低29位,即可获取当前工作者数量

Execute方法过程:

(1)、首先得到ctl数值,判断当前的工作者数量是否小于预定的核心工作者数量,如果小于则调用addWorker()方法,如果不满足看(3)

(2)、addWorker()方法:

首先会根据当前状态判断是否能够添加新任务:

a、如果当前状态大于shutdown,不能添加新任务

b、如果当前状态等于shutdown,且firstTask不等于null,不能添加新任务

c、如果当前状态等于shutdown,且firstTask等于null,且队列为空,不能添加新任务

然后进入第二层无限for循环,在此判断当前工作真数量是否大于核心工作真数量,如果大于则不能添加新任务,如果满足则需要将当前工作者数量增加1,调用的是compareAndIncrementWorkerCount如果增加1成功则返回true,如果不成功则说明这期间有其他的线程已经修改原来的数值,则进而判断状态是否已经改变,如果已经改变则继续最开始循;如果未改变则进入内层无限for循环,重新获取最新值,再次重复判断,最终要么成功增加1,要么当前工作者数量大于核心工作者数量,不能添加新任务而退出

compareAndIncrementWorkerCount增加1成功,则往下执行:将新增的任务包装成Worker类,然后加锁(加锁的原因则是因为需要将worker添加到成员变量workers中),再次判断状态(小于shutdown或者等于shutdown但是任务为null),满足条件将worker添加到workers中,解锁,若添加成功则启动worker(详解看(4)),若启动不成功,则需要将worker从workers中移除,并且将ctl值减一

 

(3)、如果当前状态是running,且将任务添加到队列成功(此队列为LinkedBlockingQuene,双向链表),则再次检测状态,如果已经改变了状态且将任务成功从队列中remove,则调用拒绝策略(此处为AbsortPolicy,实际上是抛出异常),如果还在running状态,但是当前工作者数量已经为0,则添加一个空的工作者;如果当前状态不是running,则尝试去执行任务即调用addWork(),如果不成功则调用拒绝策略

(4)、执行任务过程:

任务启动调用的是Worker类中的thread的start方法,实际上构造Thread类的时候传入的就是Worker实例本身,所以start实际执行的就是Worker的run方法,run方法中调用了runWorker方法,runWorker方法中调用了任务的run方法

 

RunWorker()方法:

首先取出Worker的firstTask赋值给task,然后将firstTask置为空,则判断task是否null,不为null则先获取锁,然后执行firstTask的run方法(即我们自定义的runnable),执行完以后则从队列中取任务,此时调用的是getTask()方法

 

GetTask()方法:

循环从队列中取任务,返回null的条件:

a、如果状态时shutdown且队列为null,则返回null

b、如果状态大于shutdown则返回null

c、如果工作者数量大于所允许的最大工作者数量,且能够将ctl值减一,则返回null

(还有一些条件存在疑问,待研读)

fixedThreadPool使用take()获取队列中的任务(poll()方法有待研读)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值