上文:https://blog.csdn.net/TomCosin/article/details/82748312
在项目中一般使用线程池来进行异步、多线程操作,但是在创建线程池时也会又各种情况,比如说使用jdk自带的Executors,在某些情况下会出现一些问题。
如上面提示所说,使用Executors在实际项目中运行的确会有各种风险。
那么我们就需要手动的创建线程池。先上一张线程池相关类的关系:
我们这里用的类是ThreadPoolExecutor,他的参数最多的构造方法是这样的:
corePoolSize和maximumPoolSize是核心线程和最大线程大小,如果是固定线程大小,这两个设置一样的大小。
keepAliveTime:当线程数量大于核心线程时,多的线程在等待新任务的最大时间。
workQueue:用来存放线程队列的集合
threadFactory:线程工厂
handler:拒绝策略
现在来看这个线程池是怎么执行的:
翻译一下这三段话:
1.如果当前运行线程小于corePoolSize,则命令创建新的线程作为首要任务,调用addWorker(添加工作者)自动检查runState(运行状态)和workerCount(工作数),因此当无法添加线程时会返回false。
2.如果任务已经成功的进入队列(这里的队列应该就是指构造参数中的workQueue),我们还是会检查我们是否应该新建一个线程(因为自从最近一次检查后,存在线程死亡状态)或者从进入这个方法后线程池被关闭。因此我们重复检查状态、在队列停止时是否需要回滚、如果没有线程是否启动新的线程。
3.如果我们不能进行队列任务,则我们会创建一个新线程。如果失败,我们会停止,并且知道如何进行拒绝任务策略。
接下来看代码:
在满足条件的情况下会进行执行addWorker方法
ThreadPoolExecutor大致执行流程可以总结一下:
1.任务执行时,先去判断能否添加任务 :
一是判断corePoolSize是否满足,二是是否能够进队列workQueue(Executors的newFixedThreadPool方法没有指定队列长度,所以会默认最大数值)
2.添加任务后,执行时从ThreadFactory中newThread,之后启动线程。