
线程池实现原理-2
前言
addWorker实现
在看addWorker方法之前,我们先看一个例子,了解一下retry的使用
- break retry 跳到retry处,且不再进入循环
- continue retry 跳到retry处,且再次进入循环
这里说一下Runnable 参数的含义
- firstTask != null 说明任务被添加了,我们需要启动一个线程去执行它
- fistTask == null 说明我只想启动一个线程去消费阻塞队列中的任务
仔细理解一下这段代码,其实就能理解,当线程池处于RUNNING 接受新任务,并且处理进入队列的任务,处于SHUTDOWN 不接受新任务,处理进入队列的任务,剩余状态都不会处理任务,上面代码中的注释有详细解释
线程池在执行任务的时候,会把任务对象包装成一个Worker对象,Worker对象是ThreadPoolExecutor的一个内部类,继承了AbstractQueuedSynchronizer,实现了一个独占锁,status值为0表示未锁定状态,status值为1表示锁定状态,实现了Runnable接口,在执行run方法的时候,它执行完初始化的firstTask后,还会从workQueue中取出任务执行,这样就不用新建一个线程执行任务,而是在一个线程中执行了好几个任务
Worker内部类
runWorker实现
当t.start()被执行后,run方法会执行runWorker方法,来看runWorker方法
这个方法需要注意的就是
- getTask()从阻塞队列中获取任务,如果队列中没有任务会被阻塞,并不会占用CPU资源
- 可以根据业务需要自定义beforeExecute和afterExecute方法
getTask实现
processWorkerExit实现
线程执行完毕执行的方法
shutdown实现
这里需要注意的是不会中断正在运行的线程,因为正在运行的线程w.tryLock()会返回false
shutdownNow实现
shutdownNow会中断所有的线程,因为和shutdown相比在中断之前,不用获取锁
tryTerminate实现
从上面可看出状态转换的条件
- SHUTDOWN想转化为TIDYING,需要workQueue为空,同时workerCount为0
- STOP转化为TIDYING,需要workerCount为0
文章转载自公众号:Java识堂
