1. 前言
在阅读研究线程池的源码之前,一直感觉线程池是一个框架中最高深的技术。研究后才发现,线程池的实现是如此精巧。本文从技术角度分析了线程池的本质原理和组成,同时分析了JDK、Jetty6、Jetty8、Tomcat的源码实现,对于想了解线程池本质、更好的使用线程池或者定制实现自己的线程池的业务场景具有一定指导意义。
2. 使用线程池的意义
复用:类似WEB服务器等系统,长期来看内部需要使用大量的线程处理请求,而单次请求响应时间通常比较短,此时Java基于操作系统的本地调用方式大量的创建和销毁线程本身会成为系统的一个性能瓶颈和资源浪费。若使用线程池技术可以实现工作线程的复用,即一个工作线程创建和销毁的生命周期期间内可以执行处理多个任务,从而总体上降低线程创建和销毁的频率和时间,提升了系统性能。
流控:服务器资源有限,超过服务器性能的过高并发设置反而成为系统的负担,造成CPU大量耗费于上下文切换、内存溢出等后果。通过线程池技术可以控制系统最大并发数和最大处理任务量,从而很好的实现流控,保证系统不至于崩溃。
功能:JDK的线程池实现的非常灵活,并提供了很多功能,一些场景基于功能的角度会选择使用线程池。
3. 线程池技术要点:
从内部实现上看,线程池技术可主要划分为如下6个要点实现:
图1线程池技术要点
工作者线程worker:即线程池中可以重复利用起来执行任务的线程,一个worker的生命周期内会不停的处理多个业务job。线程池“复用”的本质就是复用一个worker去处理多个job,“流控“的本质就是通过对worker数量的控制实现并发数的控制。通过设置不同的参数来控制worker的数量可以实现线程池的容量伸缩从而实现复杂的业务需求
待处理工作job的存储队列:工作者线程workers的数量是有限的,同一时间最多只能处理最多workers数量个job。对于来不及处理的job需要保存到等待队列里,空闲的工作者work会不停的读取空闲队列里的job进行处理。基于不同的队列实现,可以扩展出多种功能的线程池,如定制队列出队顺序实现带处理优先级的线程池、定制队列为阻塞有界队列实现可阻塞能力的线程池等。流控一方面通过控制worker数控制并发数和处理能力,一方面可基于队列控制线程池处理能力的上限。
线程池初始化:即线程池参数的设定和多个工作者workers的初始化。通常有一开始就初始化指定数量的workers或者有请求时逐步初始化工作者两种方式。前者线程池启动初期响应会比较快但造成了空载时的少量性能浪费,后者是基于请求量灵活扩容但牺牲了线程池启动初期性能达不到最优。
处理业务job算法:业务给线程池添加任务job时线程池的处理算法。有的线程池基于算法识别直接处理job还是增加工作者数处理job或者放入待处理队列,也有的线程池会直接将job放入待处理队列,等待工作者worker去取出执行。
workers的增减算法:业务线程数不是持久不变的,有高低峰期。线程池要有自己的算法根据业务请求频率高低调节自身工作者workers的数量来调节线程池大小,从而实现业务高峰期增加工作者数量提高响应速度,而业务低峰期减少工作者数来节省服务器资源。增加算法通常基于几个维度进行:待处理工作job数、线程池定义的最大最小工作者数、工作者闲置时间。
线程池终止逻辑:应用停止时线程池要有自身的停止逻辑,保证所有job都得到执行或者抛弃。
4. 几种线程池的实现细节
结合上面的技术点,列举几种线程池实现方式。
工作者workers与待处理工作队列实现方式举例:
线程池初始化与处理业务job算法举例:
线程池工作者worker的增减机制举例:
5. 小结
对比几种线程池实现,JDK的实现是最为灵活、功能最强且扩展性最好的,Tomcat即基于JDK线程池功能扩展实现,复用原有业务的同时扩充了自己的业务。Jetty6是完全自己定制的线程池业务,耦合线程池众多复杂的业务逻辑到线程池类里面,逻辑相对最为复杂,扩展性也非常差。Jetty8相对Jetty6的实现简化了很多,其中利用了JDK中的同步容器和原子变量,同时实现方式也越来越接近JDK。
6. 参考源码
JDK源码类:java.util.concurrent.ThreadPoolExecutor
Jetty6源码类:org.mortbay.thread.QueuedThreadPool
Jetty8源码类:org.eclipse.jetty.util.thread.QueuedThreadPool
Tomcat源码类:org.apache.tomcat.util.threads.ThreadPoolExecutor
http://it.dataguru.cn/article-6890-1.html
|
- 浏览: 1917340 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
x593106671:
写的真不错
对研发团队里技术分享的一些思考 -
Ann-phei:
大神 您好~我是博文视点编辑安娜,可否加我微信或QQ 8030 ...
ElasticSearch的Java Api基本操作入门指南 -
feifeiwudi:
feifeiwudi 写道发现了一个 Elasticsearc ...
ElasticSearch的Java Api基本操作入门指南 -
feifeiwudi:
发现了一个 Elasticsearch 2.3.3 JAVA ...
ElasticSearch的Java Api基本操作入门指南 -
风火轮子:
基于大数据技术推荐系统算法案例实战教程网盘下载:https:/ ...
大数据/数据挖掘/推荐系统/机器学习相关资源
摘要: 1. 前言在阅读研究线程池的源码之前,一直感觉线程池是一个框架中最高深的技术。研究后才发现,线程池的实现是如此精巧。本文从技术角度分析了线程池的本质原理和组成,同时分析了JDK、Jetty6、Jetty8、Tomcat的源码 ...
发表评论
-
诸神之黄昏:2021年以后的互联网及新兴行业
2021-10-11 12:09 318截止2021年4月,在港股 ... -
万字总结Java 9~15新特性
2021-09-11 21:36 447Java9 发布于 2017 年 9 月 21 日 。作为 ... -
从 Web 图标演进历史看最佳实践
2021-07-26 10:21 1025一、使用独立图片 在过去有很长一段时间,前端是通过引入图片 ... -
架构制图:工具与方法论
2021-07-18 20:08 1017架构制图:工具与方法论 前言 “架构制图”这词乍 ... -
性能优化
2021-07-18 19:56 931性能问题和Bug不同,后 ... -
【冬察冬见】FFmpeg系列学习笔记
2021-03-16 18:32 662【冬察冬见】FFmpeg系列 ... -
有关创新的一些思考
2021-03-04 16:41 497引子 创造力是人类最变通的工具,创造机会 ... -
浅谈面试官的培养
2021-03-04 16:38 464技术面试是一个工程师成长到一定阶段后必然要承担的一项工作,优 ... -
冬察冬见·全视角再议晋升
2021-03-02 17:48 427冬察冬见·全视角再议晋升 【前言】 又是一年春来 ... -
冬察冬见·晋升-晋升的那些事儿1
2021-03-04 11:34 22342020.08.20 集团技术通道各个子通道通过直播向所有 ... -
物联网MQTT实战
2020-11-04 16:08 6160、MQTT服务器选型 比较流行的开源 MQTT ... -
大小公司都适用的架构选型工具箱(涵盖上百个组件)
2020-10-17 21:20 366本篇内容涵盖14个方面,涉及上百个框架和工具。会有你喜 ... -
读书与成长
2020-10-16 10:52 263《论语》里说:⾏有余 ... -
2020年教育行业OMO模式转型现状研究报告
2020-08-28 16:39 292OMO 模式是教育行业近十年的主流趋势,机构要选择的并非是是 ... -
百度的71个非常厉害的开源项目
2020-08-18 12:47 4281.JavaScript图表库 EChartsEChart ... -
最好的励志书
2020-08-09 21:14 360最好的励志书是促使你马上采取行动或者觉得自己必须马上采取行 ... -
心智成长
2020-08-07 22:50 317——来自《哈佛商业评论》的文章 伟大的领导人与一般领 ... -
研发路上的一些总结与思考
2020-07-27 17:07 445技术层面 对开发同学 ... -
MQTT协议为什么这么轻量级
2020-07-25 22:24 8331、MQTT协议如何做到轻 ... -
高效沟通
2020-07-23 14:55 394为什么沟通那么重要 谁都知道在工作中沟通是非常重要的,那大 ...
相关推荐
动态代理的几种方式 HashMap的并发问题 了解LinkedHashMap的应用吗 反射的原理,反射创建类实例的三种方式是什么? cloneable接口实现原理,浅拷贝or深拷贝 Java NIO使用 hashtable和hashmap的区别及实现原理,...
第八题 Java并发类库提供的线程池有哪几种 分别有什么特点.pdf 第六题 synchronized和ReentLock有什么区别.pdf 第四题 ArrayList LinkedList Vector的区别.pdf docker讲得最清楚.doc Dubbo是什么?能做什么?.doc ...
该实例可进行局域网的聊天、一对多、多对一、和多对多的传送和续传,理论上这是我本人的实现目的,而且目前经测试已基本实现了上述功能,而且网速一般有几M/S。另外有只打开一个应用程序、CRichEdit的使用、最小到...
该实例可进行局域网的聊天、一对多、多对一、和多对多的传送和续传,理论上这是我本人的实现目的,而且目前经测试已基本实现了上述功能,而且网速一般有几M/S。另外有只打开一个应用程序、CRichEdit的使用、最小到...
该实例可进行局域网的聊天、一对多、多对一、和多对多的传送和续传,理论上这是我本人的实现目的,而且目前经测试已基本实现了上述功能,而且网速一般有几M/S。另外有只打开一个应用程序、CRichEdit的使用、最小到...
该实例可进行局域网的聊天、一对多、多对一、和多对多的传送和续传,理论上这是我本人的实现目的,而且目前经测试已基本实现了上述功能,而且网速一般有几M/S。另外有只打开一个应用程序、CRichEdit的使用、最小到...
该实例可进行局域网的聊天、一对多、多对一、和多对多的传送和续传,理论上这是我本人的实现目的,而且目前经测试已基本实现了上述功能,而且网速一般有几M/S。另外有只打开一个应用程序、CRichEdit的使用、最小到...
该实例可进行局域网的聊天、一对多、多对一、和多对多的传送和续传,理论上这是我本人的实现目的,而且目前经测试已基本实现了上述功能,而且网速一般有几M/S。另外有只打开一个应用程序、CRichEdit的使用、最小到...
高并发编程第三阶段12讲 sun.misc.Unsafe介绍以及几种Counter方案性能对比.mp4 高并发编程第三阶段13讲 一个JNI程序的编写,通过Java去调用C,C++程序.mp4 高并发编程第三阶段14讲 Unsafe中的方法使用,一半是...
高并发编程第三阶段12讲 sun.misc.Unsafe介绍以及几种Counter方案性能对比.mp4 高并发编程第三阶段13讲 一个JNI程序的编写,通过Java去调用C,C++程序.mp4 高并发编程第三阶段14讲 Unsafe中的方法使用,一半是...
Java并发:三种锁,validate,synchronized,lock,CAS,线程池(原理和拒绝策略),多线程工具类 操作系统:死锁条件与避免,页式存储管理,页面置换算法,线程与进程区别,假脱机,存储模型 数据库:写SQL,几个...
收集几个参与社区投稿、开源项目的途径 博文收集(敖丙系列&芋道源码系列) 注 : 没链接的是还没写 Java基础核心串讲 计算机操作系统与Linux 7种常见的设计模式和使用场景 Java必会基础与新版本特性 集合框架 深入浅...
6、优化“时间_取中国星期几”命令,感谢易友【灵魂出窍808】提议。 7、新增“网页_取网络文件尺寸”获取网络文件尺寸,失败返回零。 8、新增“数组_取次数”,取指定数组成员出现相同数量,源码由易友【C盘是头猪】...