文章持续更新,微信搜索「 万猫学社 」第一时间阅读。
关注后回复「 电子书 」,免费获取12本Java必读技术书籍。

餐厅的约会

餐盘在灯光的照耀下格外晶莹洁白,女朋友拿起红酒杯轻轻地抿了一小口,对我说:“经常听你说线程池,到底线程池到底是个什么原理?”我楞了一下,心里想女朋友今天是怎么了,怎么突然问出这么专业的问题,但做为一个专业人士在女朋友面前也不能露怯啊,想了一下便说:“我先给你讲讲我前同事老王的故事吧!”

大龄程序员老王

老王是一个已经北漂十多年的程序员,岁数大了,加班加不过年轻人,升迁也无望,于是拿着手里的一些积蓄,回老家转行创业。他选择了洗浴行业,开一家洗浴中心,没错,一家正规的洗浴中心。之前在北京的时候,喜欢去的澡堂叫“清华池”,他想了想,就给自己的洗浴中心取名为“线程池”。

线程池洗浴中心

线程池开业以后,老王发现有顾客想做足疗,于是就招聘了1个足疗技师,多增加了一项业务增加了收入。随着做足疗的顾客增多,为了赚更多钱又招聘了4个足疗技师。
过了一段时间,洗浴中心的生意越来越好,做足疗的顾客也越来越多。但是,老王发现自己店里的足疗技师已经有5个足疗技师,再招聘就太多了,支付不起再多工资了。足疗技师忙不过来怎么办?老王是个聪明人,马上想到办法:让顾客排队,有哪个足疗技师做完了,空闲出来了,就在队伍里再叫一个顾客继续做。

忙碌的周末

一到周末,来洗浴中心的顾客比平时多了几倍,想足疗的顾客排队时间太长,顾客们已经不耐烦了。老王马上做出反应,又紧急从其他洗浴中心招聘了5个足疗技师,为队伍里顾客做足疗,大大减少排队的顾客。
不过,有时生意太火爆了,紧急招聘的技师也用上了,顾客排队时间也是很长,再来新的顾客,老王只能满脸赔笑地和顾客说:“您下次再来吧,下次给您找个好技师。”,把顾客拒之门外。
过了周末以后,店里不能养闲人啊,老王就把紧急招聘的技师都辞退了。

老王的经营之道

老王的生意越做越红火,很快就要开分店、融资上市、走上人生巅峰。既然这么成功,就让我们来复盘一下他的经营之道吧:

如果你了解了老王的经营之道,线程池就不难理解了,把顾客替换成任务,把足疗技师替换成线程线程池洗浴中心就是线程池了,线程池的内部原理就是这样的:

梦醒

铃铃铃,闹铃把我吵醒,原来是一场梦啊,我哪有什么女朋友?今天上午有一个面试,赶紧起床洗漱完毕,就出发了。在路上回想那个奇怪的梦,要不再复习一下线程池的内部原理吧!
先看一下ThreadPoolExecutor类的execute方法:

public void execute(Runnable command) {if (command == null)throw new NullPointerException();//获取clt,clt记录着线程池状态和运行线程数。int c = ctl.get();//运行线程数小于核心线程数时,创建线程放入线程池中,并且运行当前任务。if (workerCountOf(c) < corePoolSize) {if (addWorker(command, true))return;//创建线程失败,重新获取clt。c = ctl.get();}//线程池是运行状态并且运行线程大于核心线程数时,把任务放入队列中。if (isRunning(c) && workQueue.offer(command)) {int recheck = ctl.get();//重新检查线程池不是运行状态时,//把任务移除队列,并通过拒绝策略对该任务进行处理。if (! isRunning(recheck) && remove(command))reject(command);//当前运行线程数为0时,创建线程加入线程池中。else if (workerCountOf(recheck) == 0)addWorker(null, false);}//运行线程大于核心线程数时并且队列已满时,//创建线程放入线程池中,并且运行当前任务。else if (!addWorker(command, false))//运行线程大于最大线程数时,失败则拒绝该任务reject(command);
}

在execute方法中,多次调用的addWorker方法,再看一下这个方法:

private boolean addWorker(Runnable firstTask, boolean core) {retry:for (;;) {//获取clt,clt记录着线程池状态和运行线程数。int c = ctl.get();//获取线程池的运行状态。int rs = runStateOf(c);//线程池处于关闭状态,或者当前任务为null//或者队列不为空,则直接返回失败。if (rs >= SHUTDOWN &&! (rs == SHUTDOWN &&firstTask == null &&! workQueue.isEmpty()))return false;for (;;) {//获取线程池中的线程数int wc = workerCountOf(c);//线程数超过CAPACITY,则返回false;//这里的core是addWorker方法的第二个参数,//如果为true则根据核心线程数进行比较,//如果为false则根据最大线程数进行比较。if (wc >= CAPACITY ||wc >= (core ? corePoolSize : maximumPoolSize))return false;//尝试增加线程数,如果成功,则跳出第一个for循环if (compareAndIncrementWorkerCount(c))break retry;//如果增加线程数失败,则重新获取ctlc = ctl.get();//如果当前的运行状态不等于rs,说明状态已被改变,//返回第一个for循环继续执行if (runStateOf(c) != rs)continue retry;}}boolean workerStarted = false;boolean workerAdded = false;Worker w = null;try {//根据当前任务来创建Worker对象w = new Worker(firstTask);final Thread t = w.thread;if (t != null) {final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {//获得锁以后,重新检查线程池状态int rs = runStateOf(ctl.get());if (rs < SHUTDOWN ||(rs == SHUTDOWN && firstTask == null)) {if (t.isAlive())throw new IllegalThreadStateException();//把刚刚创建的线程加入到线程池中workers.add(w);int s = workers.size();//记录线程池中出现过的最大线程数量if (s > largestPoolSize)largestPoolSize = s;workerAdded = true;}} finally {mainLock.unlock();}if (workerAdded) {//启动线程,开始运行任务t.start();workerStarted = true;}}} finally {if (! workerStarted)addWorkerFailed(w);}return workerStarted;
}

面试

一个穿着格子衬衫的中年男子坐在我面前,对我说:“您好,我是今天的面试官。”我微笑地回应:“您好。”面试官面无表情地问我:“线程池一定用过吧,能说说线程池的内部原理嘛?”我差点笑出声来,自信满满地说……

文章持续更新,微信搜索「 万猫学社 」第一时间阅读。
关注后回复「 电子书 」,免费获取12本Java必读技术书籍。

给女朋友讲 : Java线程池的内部原理相关推荐

  1. 基于java洗浴中心管理系统_Java小白也能听懂的线程池的内部原理:老王的洗浴中心...

    餐厅的约会 餐盘在灯光的照耀下格外晶莹洁白,女朋友拿起红酒杯轻轻地抿了一小口,对我说:"经常听你说线程池,到底线程池到底是个什么原理?"我楞了一下,心里想女朋友今天是怎么了,怎么突 ...

  2. Java线程池的实现原理,你清楚么?

    点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/u013332124/article/details/79587436 原理概述 其实java线程池的实现原理很简单,说白了就是 ...

  3. Java 线程池的工作原理

    文章目录 概念 线程中的基本方法 线程复用 线程池的核心组件和核心类 线程池的工作原理 线程池中的workQueue任务队列 直接提交队列(SynchronousQueue) 有界任务队列(Array ...

  4. 深入源码分析Java线程池的实现原理

    转载自   深入源码分析Java线程池的实现原理 程序的运行,其本质上,是对系统资源(CPU.内存.磁盘.网络等等)的使用.如何高效的使用这些资源是我们编程优化演进的一个方向.今天说的线程池就是一种对 ...

  5. 码仔漫画:怎么给女朋友讲明白线程池?

    码个蛋(codeegg)第 637 次推文 作者:iMononoke 博客:https://juejin.im/user/5c629a3051882562191755d8 前言 线程池是Java面试必 ...

  6. 好文推荐:深入分析Java线程池的实现原理

    线程是稀缺资源,如果被无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,合理的使用线程池对线程进行统一分配.调优和监控,有以下好处: 1.降低资源消耗: 2.提高响应速度: 3.提高线程的可管理 ...

  7. 全面解读Java线程池的工作原理

    目录 一.为什么引入线程池技术? 二.Executor框架 2.1 Runnable.Callable与Future接口 2.2 Executor接口 2.2.1 Executor 2.2.2 Exe ...

  8. 彻底搞懂Java线程池的工作原理

    一.线程池的基础知识 创建线程需要占用一定的操作系统资源,在高并发情况下,频繁的创建和销毁线程会大量消耗CPU和内存资源,对程序性能造成很大的影响.为了避免这一问题,Java提供了线程池(通过线程复用 ...

  9. Java线程池及其实现原理

    线程池概述 线程池(Thread Pool)是一种基于池化思想管理线程的工具,经常出现在多线程服务器中,如MySQL. 线程过多会带来额外的开销,其中包括创建销毁线程的开销.调度线程的开销等等,同时也 ...

最新文章

  1. 深入理解定位父级offsetParent及偏移大小
  2. Linux 下的常用工具
  3. 显示照片的二维直方图
  4. jquery-autocomplete学习(转)
  5. python笔记-1(import导入、time/datetime/random/os/sys模块)
  6. 知道这些用于数据科学和机器学习的GitHub存储库和Reddit主题吗?
  7. Keras-6 IMDB, a binary classification example
  8. java字符后移_java把字符串参数往后移3位后输出
  9. java php json转字符串_php json字符串转为数组或对象
  10. 语音识别的技术原理是什么?
  11. leetcode—15.链表双指针题目python解答
  12. storm发布jar包时报找不到主类_咖啡5元一大包,进口饼干10元3包…济南有个临期食品超市,快过期的食品你会买单吗...
  13. 【重点】commons-dbutils
  14. #今日说码栏目#第四集 各类选择器
  15. java中的JAR包
  16. 微信小程序:从小程序打开H5页面
  17. outline与border的区别
  18. 电子商务案例:联邦快递公司成功模式
  19. 微信公众号开发(一)--公众号关注推送
  20. java 保险管理系统_保险管理系统

热门文章

  1. 微众银行眼中的区块链分布式商业趋势及技术落地
  2. 大数据Hadoop学习系列之Hadoop、Spark学习路线
  3. 27条好赚钱副业的忠告:自己也能月入2万+!
  4. 爱奇艺内容中台之数据中心的设计与实现
  5. 预测算法-线性回归(鲍鱼年龄预测)
  6. 潘老师课堂开讲!!!
  7. IIs_WPG用户组的介绍
  8. python2安装pycrypto
  9. 这次是真的再见了,oi退役回忆录
  10. 经济内循环时代,我们需要更多的“云网万店”新物种