java并发线程池ThreadPoolExecutor深入剖析最经典

本文为原创文章,转载请注明出处,谢谢你……

> 喜欢java并发编程的请加群:736156823

开始-->

先吐槽:

网上有很多介绍线程池的文章,都是抄的,没劲,没一个流程图,没有一个是从submit开始到内部流转在到执行的,像我这种小白能看懂?老奶奶能看懂吗?就连这么有生活阅历的人都看不懂,你写他还有什么用呢?不是在浪费资源吗?反正上来就是先吐槽,自己爽了,然后再说。但是我觉得这个吐槽还不给力,所以就直接写一篇文章吧。哈哈,上述都是废话,没什么用处,乐呵乐呵就好了,哈哈……

直接干:

1.环境:为了靠谱点,装了个最新的jdk,哎呀,好麻烦,烦躁……版本:jdk-8u121-windows-x64;

2.继承关系:


ThreadPoolExecutor继承结构

3.创建ThreadPoolExecutor后直接提交runnable的流程图如下:

ThreadPoolExecutor中submit流程图

说明:其中的什么接口啦,什么实现类啊,靠,不说了,没劲……然后就是生成runnableFuture对象的方法,太简单了……然后基本就没啥了,关键是要有流程图,有了这个谁还愿意看代码?而且就只是那干巴巴的代码一摆就得了?哼……没劲……下面给出源代码截图:

submit源代码
构造RunnableFuture源代码

4.ThreadPoolExecutor中的execute方法流程图:

execute方法流程图
execute方法源代码

说明:

1)针对AtomicInteger类型ctl参数的说明,ctl是一个 AtomicInteger 类型, 它的低29位用于存放当前的线程数, 因此一个线程池在理论上最大的线程数是536870911; 高 3 位是用于表示当前线程池的状态, 其中高三位的值和状态对应如下:

111: RUNNING;

000: SHUTDOWN;

001: STOP;

010: TIDYING;

110: TERMINATED;

2)workerCountOf方法获取线程池当前有效的线程数量,实现很简单,不说了;

3)corePoolSize,核心线程数。当线程池中的任务缓存队列还没有被填充满时,线程池中允许的最多的有效的线程数量;

4)addWorker方法,正真的将任务添加到线程池,并且执行启动线程即调用Thread.start()方法的方法。内部执行流程会在下面给出;

5)isRunning方法,判断线程池状态的方法。实现简单,不说了;

6)remove方法,移除任务。简单,不说了,至于内部的tryTerminate方法,后面给出;

7)reject方法,线程池如何拒绝任务提交的方法策略。这个和线程池的初始化参数有关,后面介绍,也比较简单,不多说。

8)为什么要这么多的判断?判断这些又有什么用呢?

“workerCountOf(c) < corePoolSize”判断,主要为了判断当前线程池中活跃线程的数量是否大于核心线程数,如果大于那么会将这个任务方到阻塞队列中,如果小于那么就会直接创建新的线程去执行;如果调用addworker方法成功了,那么就直接返回了,如果失败了就重新获取当前线程数量继续执行下面的代码。

“isRunning(c) && workQueue.offer(command)”这个判断,主要是为了判断当前线程池是否是活跃的,并且在这种情况下能否提交任务成功,如果当前线程池不活跃,那么会继续下面的其他判断;如果当前的状态是活跃的,那么会将任务提交到队列中,如果提交失败同样会继续下面其他的判断,如果提交成功会进入内部判断;

“! isRunning(recheck) && remove(command)”这个判断,提交队列成功后在此次判断当前线程池的状态,如果被关闭,那么将任务删除,再调用拒绝策略;

“workerCountOf(recheck) == 0”这个判断,主要为了防止所有线程恰好在新的任务提交成功后却都到了最大存活时间而消亡了,造成没有线程到队列中去取任务执行,为了防止bug出现,哈哈;

“!addWorker(command, false)”这个判断主要为了处理在队列被填满,但是活跃的线程数还没有达到最大线程数maximumPoolSize的情况,如果这个也失败了,那就拒绝了。

这些判断还有一些其他的作用,要整体来看,这里给出主要作用,后面会补充,如果你从头到尾看完此文章,这些整体上的作用相信你也会体会到的。

execute整体流程说明如下图:

execute整体流程说明Part1
execute整体流程说明Part2

5.addWorker方法流程图:

addWorker方法流程图

再补一个同样的流程,上面的是图片,简书有时候刷不出来,编辑都出不来,哎……

addWorker方法流程图(副本)

说明:

1)针对上图中的菱形条件判断,顺序是以从上到下,从左到右为顺序;

2)第一条件判断,源代码如下图:

条件判断0

首先,如果‘rs >= SHUTDOWN’结果为false,那么将不会继续下面的判断,那么会继续走下面的流程,因为结果为false说明当前线程池还是可提交(运行)状态,所以直接继续,并不执行return false语句。第二种情况,如果第一个判断为true,那么进入if的下一个判断‘! (rs == SHUTDOWN &&firstTask == null &&! workQueue.isEmpty())’,因为第一个判断为true,所以rs的值可能rs = = SHUTDOWN或者rs > SHUTDOWN,如果rs == SHUTDOWN,那么内部的判断将会继续,会继续判断firstTask==null,如果为null那么继续向下判断! workQueue.isEmpty(),说了这么多,有没有感觉很乱,是的我都乱了,所以,还是直接翻译成流程图吧……哈哈,好期待,下面给出第一个菱形条件判断的流程图:

第一个条件判断的判断流程

说明:上图是第一个条件判断语句if里面的内容,具体转换,往下看。

下面给出代码上的转换:

第一个条件判断在代码上的转换

说明:上图中上面注释调的部分为源代码。其中源代码中的执行流程被返回的true替代了,这里就是示意一下。就不进行文字描述了,流程图已经说得很明白了,如果图还看不懂的话,老衲也无能为力了,还请师太帮忙……哈哈……。其实上面注意的是那些变量的判断,为什么要那样判断呢?这个问题和线程池的整体策略有关,要全部说完才行,先记下来,接着往下说。

3)第二个菱形条件判断源代码:

第二个条件判断源代码

判断流程代码转换:

第二个条件判断流程代码转换

判断的具体流程图:

第二个条件判断的流程图

说明:

4)第五个菱形条件判断源代码:

第五个菱形条件判断源代码

形式上的代码转换如下:

第五个菱形判断的代码转换

使用流程图表示如下:

第五个菱形判断的流程图

说明:太简单了,代码转换,流程图看起来很容易,不解释了。

5)简单总结一下:在addWorker中的主要的流程判断都已经给出,其他的很简单的就不说明了。其实,这里面比这些判断还重要的是为什么要进行这样的判断和判断这些是为了什么?还有一个比较重要的是addWorker方法了里面调用的一些其他的内部方法,所以请好好看下针对每个判断下面的说明,重点介绍了为什么要那么判断,原因理由目的。是的,如果上面的针对判断的说明没有介绍的太清楚或者还有什么疏漏,这些后面都还会有详细的补充介绍并加以说明。下面给出addWorker的源代码截图:

addWorker方法源代码

6)整体代码说明:

addWorker代码说明part1
addWorker代码说明part2

好了,先告一段落,继续下面的方法。

6.tryTerminate方法流程

tryTerminate方法流程图

说明:

1.全部说明见下图:

tryTerminate方法流程说明

7.processWorkerExit方法流程

processWorkerExit方法流程图

说明:

processWorkerExit方法流程说明

8.getTask方法流程

getTask方法流程图

说明:

getTask方法说明Part1
getTask方法说明Part2
getTask方法说明Part3

9.runWorker方法流程

runWorker方法流程图

说明:

runWorker方法流程说明Part1
runWorker方法流程说明Part2
runWorker方法流程说明Part3

>下面给出本人的代码github地址:

https://github.com/baojie5642/hahathreadpool

> 喜欢java并发编程的请加群:736156823

大大的总结:

这篇文章很早就创建了,但是一致没搭理,最开始是eclipse,后面确实idea,本文格式太丑(自己讨太蠢了),哈哈……

文章里面的错误欢迎大家指正,么么哒……

后面补上的内容是使用的jdk8最新64版本代码……

本文为原创文章,转载请注明出处,谢谢你……

结束-->

哈哈给您请安了……

拜拜……

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容