+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2019-07(1)

2019-08(109)

2019-09(120)

2019-10(17)

2019-11(1)

Java线程池的工作原理,以故事白话文讲底层干货。

发布于2020-10-25 09:58     阅读(281)     评论(0)     点赞(23)     收藏(3)


0

1

2

3

4

5

6

7

8

前言

1024,节日快乐!

本文以程序员做需求的例子,比喻线程池的工作过程。以故事白话的方式展开,跟大家阐述线程池工作原理,以方便大家更好理解线程池,谢谢阅读哈~

线程池在面试中基本上已经是必问项了,面试官通常会从简单的问题开始发问,然后再一步一步的挖掘你的知识面。本文稍微有点长,耐心阅读!

另外也整理了Java的核心知识点和各个大厂面试题和视频,需要的朋友可以点击:点这个,点这个,暗号:csdn。
在这里插入图片描述

什么是线程池?

小田螺 勤勤恳恳,任劳任怨,夜以继日地工作,终于有一天,他晋升为公司的主管,负责公司日常业务。

有一天,老板找到了小田螺,“我们公司员工越来越多了,我想搞个员工管理系统,你那边安排一下哈,要在一个月后完成。” 小田螺拍拍胸口没问题!

因为当前公司还没有程序员,所以小田螺快马加鞭打开猪八戒网,提交员工管理系统需求,等待不久,开发者(名字,线程A) 接单,谈好合同,开始开发,系统交付…一系列流程并且一个月过后,一个五脏俱全的员工管理系统终于完成了…老板对此大加赞赏~

过了不久,老板再次发话,“公司越来越多人迟到了,我们再搞个考勤系统吧!"小田螺接到任务,马上又开始上猪八戒网,提需求找人开发,这次来了线程B接单…

逝者如斯,月底了,老板又提出开发个薪酬系统需求…小田螺听了头皮发麻,one day day的,重复去网上找人开发!“为了节省成本,不如我们雇佣几个程序员(线程a,b,c),成立自己的IT技术部门吧!我们就管IT部门叫线程池吧!”老板听了,一拍即合!!!

线程池就是管理线程的池子,当有任务要处理时,不用频繁创建新线程,而是从池子拿个线程出来处理。当任务执行完,线程并不会被销毁,而是在等待下一个任务。因此可以节省资源,提高响应速度。

什么是核心线程?

线程池IT部门成立后,雇佣了几个与公司有正式合同关系的员工a,b,c,小田螺管他们几个正式员工做核心线程。当老板提一个需求过来,小田螺就把需求分配给手上没活干的线程处理…

什么是阻塞队列?

一天早上,老板睡眼惺忪。来到公司后,一口气提了四个需求,a,b,c 按顺领完任务后,发现还剩余一个需求任务。这个怎么安排呢?难道又去猪八戒兼职网找人嘛?成立了线程池IT部门,还去找人(线程干活),会被人笑落大牙的!

聪明的小田螺想到一个好办法,我们可以搞个DPMS需求池,把还没分配的需求,放进待完成的DPMS需求池里面吧,等到a,b,c谁先干完活,再把这个任务领走。这个DPMS需求池,我们给它取名阻塞队列,英文名叫WorkQueue吧!

什么是非核心线程?

又在一个晴空万里的午后,老板喝了一杯咖啡,闲来没事,就跑去阻塞队列(DPMS需求池)看看,一看就傻帽了!!需求池堆积了几十个需求,排期都是满满的了。老板马上叫小田螺进来办公室,以商量如何处理这些需求任务。

“要不,我们雇佣多几个员工(搞多几个核心线程)?” “不行不行,公司财务开销有点大!”

“要不然,我们要求业务提少点任务需求?(请求少点)” “你是不是傻,请求少点,不是自断财路嘛?你回家想想办法先吧!!”老板放大了他的嗓门~

小田螺回家闭目让神,每天早早就睡觉,两耳不闻窗外事…终于有一天,在一个梦香里,他想到了一个好办法。

“老板,我们可以去别的公司(外包公司)雇佣几个员工(假设名字为d,e,f,g)一段时间,让它们来做DPMS需求池(阻塞队列) 里面的需求。等到做完需求,再派他们回去就好啦。” 老板一听就乐了,这个方案好,心里美滋滋:需求的活有人干了,公司财务又省钱,两全其美呀~ 这几个派遣来的外包员工(d,e,f,g),我们就把它叫做非核心线程吧。

什么是空闲时间?

自从来了d,e,f,g外包员工(非核心线程),老板长舒一口气,这么多活,终于有人干了。

但是呢,又有一天,到了7点所谓的下班时间,老板走出办公室,发现线程池IT部门的员工,都走得七七八八了。心里一怒:这帮粉肠,怎么一到下班时间就跑,工作这么不饱和了?他随手点进DPMS需求池,才发现,原来需求都被做完了。。。还有一堆外包同事(非核心线程)要发工资呢,这波亏大了~

第二天,小田螺被秘密叫进了老板办公室,既然DPMS需求池都已经没需求了。我们准备派外包同事(非核心线程)回去吧?但是呢一般,需求一没有,就马上让他们回去(线程回收),如果需求一下子又来,就有点hold不住了…

“要不酱紫,我们等需求池空的时候,隔个15天还是10天,再让外包同事(非核心线程)回去吧?” 这个定义的15天或者10天,就是线程空闲存活时间啦

什么是饱和策略?

在临近双11的时候,不仅老板提了良多需求,新来的运营小姐姐们,也提了好多好多的需求。新需求如源头活水,滚滚的来~

首先呢,线程池IT部门a,b,c三个正式员工(核心线程)都忙于处理需求(请求),接着,DPMS需求池(阻塞队列)也被挤满了,最后呢,连d,e,f,g外包同事(非核心线程)也忙得不可开交。

这时候,需求还是做不完,怎么办呢?双11赶着上线呢?小田螺愁眉苦脸,从潮起愁到潮落…

没办法了,只能动用饱和策略啦。比如丢弃需求任务?抛异常,告诉老板别加需求了?丢弃需求池最老的需求任务?还是交给提需求的人自己处理?

最后老板决定,拒绝再提新的需求,于是线程池IT部门还是正常运行~

线城池的饱和策略事件,主要有四种类型

AbortPolicy(抛出一个异常,默认的) DiscardPolicy(新提交的任务直接被抛弃) DiscardOldestPolicy(丢弃队列里最老的任务,将当前这个任务继续提交给线程池) CallerRunsPolicy(交给线程池调用所在的线程进行处理,即将某些任务回退到调用者)

线程池工作原理流程图 & 源码概览

故事讲完啦,再复习下线程池工作流程图吧~
在这里插入图片描述
有兴趣的朋友,源码也看下吧~

 if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        //判断当前活跃线程数是否小于corePoolSize
        if (workerCountOf(c) < corePoolSize) {
            //如果小于,则调用addWorker创建线程执行任务
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        //如果大于等于corePoolSize,则将任务添加到workQueue队列。
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        //如果放入workQueue队列失败,则创建非核心线程执行任务    
        else if (!addWorker(command, false))
            //(如果这时创建线程失败(当前线程数大于等于maximumPoolSize时))
            调用reject拒绝接受任务
            reject(command);

最后

提供免费的Java架构学习资料,学习技术内容包含有:Spring,Dubbo,MyBatis, RPC, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。

需要的朋友可以点击:点这个!点这个!,暗号:csdn。

还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书+2020年最新大厂面试题。
在这里插入图片描述

2020年最新的大厂面试题
在这里插入图片描述
在这里插入图片描述

原文链接:https://blog.csdn.net/weixin_48011329/article/details/109261899

0

1

2

3

4

5

6

7

8

9



所属网站分类: 程序员的那点事

作者:你太美丽

链接: https://www.pythonheidong.com/blog/article/608667/ca753c36c32ede27d140/

来源: python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

23 0
收藏该文
已收藏

评论内容:(最多支持255个字符)