线程池

线程池的源码分析

2017-01-15  本文已影响31人  小鱼嘻嘻

这一节主要讲线程池ThreadPoolExecutor类中的execute方法,了解线程池的执行原理。

首先我们要明白不论是execute还是submit最终都是调用execute所有我们只需要了解execute源码就可以。

首先我们来明确一点:int c = ctl.get();其实拿到的是一个数字,这个数字是通过&运算得到的结果,这个数字里面包含了两点比较重要的数据信息第一:通过这个数字可以得到线程的状态,第二:通过这个数字可以当前线程池中线程的数量。至于怎么计算得到我们先不做考虑(我也不是很清楚)

因此我们知道第一个if判断的是当前线程池的线程数和核心线程数大小关系,如果小于核心线程数就直接将当前任务加入线程池。因此我们来看看addWorker(command,true)具体内容是什么。

 

首先是一个永真循环,拿到线程池的数量和线程池的状态做一次有效性的判断,接着又是一个永真的循环,判断线程池的数量,并且尝试将线程池的数量加1,成功之后退出。总结起来就是:对线程池数量状态做一些校验,然后不断尝试给线程池数量加1,退出条件要么校验失败,要么加1成功。

由于之前的代码已经给线程池的数量加1了所有这段代码的主要目的是把这个线程或者说任务添加到线程池里也就是hashset里。

首先会有一个加锁的操作保证原子性,然后就是判断线程池的状态和线程池的数量,如果没有问题的话就加入hashset里,并且要把当前加入的线程或者任务启动;如果加入失败的话就需要看看加入失败的代码了。

加入失败的话也很好理解:首先我们需要把这个线程从set里面移除,其次我们需要把之前线程池里面加1的数量减掉,还有一点比较特殊的就是我们需要尝试终止线程池。

好了现在拉回到我们最初的地方,这只是我们判断线程池中数量小于核心线程数的情况

如果要是大于核心线程数量的话我们需要添加到阻塞队列的,这个很简单直接添加就可以不过在添加完了是需要再次check的

如果不满足以上两种情况的话我们就需要尝试新建线程添加任务,如果失败的话就调用相应的拒绝策略就可以。

好了本节就主要讲解execute方法,相对来说线程池的执行还是比较好理解。

上一篇下一篇

猜你喜欢

热点阅读