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
|
- 浏览: 1982140 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
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 399截止2021年4月,在港股 ... -
万字总结Java 9~15新特性
2021-09-11 21:36 566Java9 发布于 2017 年 9 月 21 日 。作为 ... -
从 Web 图标演进历史看最佳实践
2021-07-26 10:21 1089一、使用独立图片 在过去有很长一段时间,前端是通过引入图片 ... -
架构制图:工具与方法论
2021-07-18 20:08 1088架构制图:工具与方法论 前言 “架构制图”这词乍 ... -
性能优化
2021-07-18 19:56 1012性能问题和Bug不同,后 ... -
【冬察冬见】FFmpeg系列学习笔记
2021-03-16 18:32 766【冬察冬见】FFmpeg系列 ... -
有关创新的一些思考
2021-03-04 16:41 561引子 创造力是人类最变通的工具,创造机会 ... -
浅谈面试官的培养
2021-03-04 16:38 526技术面试是一个工程师成长到一定阶段后必然要承担的一项工作,优 ... -
冬察冬见·全视角再议晋升
2021-03-02 17:48 486冬察冬见·全视角再议晋升 【前言】 又是一年春来 ... -
冬察冬见·晋升-晋升的那些事儿1
2021-03-04 11:34 23002020.08.20 集团技术通道各个子通道通过直播向所有 ... -
物联网MQTT实战
2020-11-04 16:08 7710、MQTT服务器选型 比较流行的开源 MQTT ... -
大小公司都适用的架构选型工具箱(涵盖上百个组件)
2020-10-17 21:20 436本篇内容涵盖14个方面,涉及上百个框架和工具。会有你喜 ... -
读书与成长
2020-10-16 10:52 317《论语》里说:⾏有余 ... -
2020年教育行业OMO模式转型现状研究报告
2020-08-28 16:39 340OMO 模式是教育行业近十年的主流趋势,机构要选择的并非是是 ... -
百度的71个非常厉害的开源项目
2020-08-18 12:47 4641.JavaScript图表库 EChartsEChart ... -
最好的励志书
2020-08-09 21:14 401最好的励志书是促使你马上采取行动或者觉得自己必须马上采取行 ... -
心智成长
2020-08-07 22:50 365——来自《哈佛商业评论》的文章 伟大的领导人与一般领 ... -
研发路上的一些总结与思考
2020-07-27 17:07 487技术层面 对开发同学 ... -
MQTT协议为什么这么轻量级
2020-07-25 22:24 9031、MQTT协议如何做到轻 ... -
高效沟通
2020-07-23 14:55 450为什么沟通那么重要 谁都知道在工作中沟通是非常重要的,那大 ...
相关推荐
在"C++线程池的实现代码"中,我们可以探讨以下几个关键知识点: 1. **线程的创建与管理**:C++11引入了 `<thread>` 头文件,提供了一种标准的方式来创建和管理线程。线程池需要能够创建线程,同时还要能将线程放入...
在Linux系统中,实现线程池通常需要掌握以下几个核心知识点: 1. **线程基础**:线程是操作系统分配CPU时间的基本单位,一个进程可以包含多个线程,它们共享进程的内存空间,但拥有各自的栈空间和程序计数器。线程...
在Java的并发编程中,线程池是一种非常重要的工具,它可以帮助我们有效地管理和控制线程的生命周期,提高系统的性能和响应速度。Java从JDK 1.5版本开始引入了线程池,使得开发者不再需要手动创建和销毁线程,而是...
开发者需要分析错误代码、状态机设计以及重试算法的实现。 4. **异常处理**:在处理网络通信问题时,异常处理是必不可少的。观察源码中如何捕获和处理网络异常,以及如何利用这些异常信息调整重试策略,有助于我们...
在分析ThreadPoolWithJobAffinity-master压缩包中的源代码时,我们可以期待看到如何实现上述组件的具体细节,包括类的设计、方法的实现以及如何将这些组件组合在一起以实现作业亲和性。可能包含以下部分: - `Job` ...
无锁线程池是线程池的一种特殊实现,它完全依赖于原子操作,避免了锁带来的竞争条件和死锁问题,从而提高了并发性能。 无锁编程是一种编程范式,它旨在避免在多线程环境下使用互斥锁。在无锁编程中,数据结构和算法...
在IT行业中,线程池是一种优化资源管理的策略,尤其在多线程编程中显得尤为重要。线程池的原理是预先创建一定数量的线程,这些线程在完成任务后并不会立即销毁,而是进入就绪状态等待新的任务分配。这样可以避免频繁...
这一部分包括以下几种模式: - **1.1 Factory模式**:定义了一个创建对象的接口,但允许子类决定实例化哪一个类。Factory方法让一个类的实例化延迟到其子类。这种模式适用于当一个类不知道它所必须创建的对象的类的...
本文将重点解析其中几种关键的设计模式,并结合C++实现源码进行深入分析。 ### 创建型模式 #### 1.1 Factory模式 Factory模式是一种创建型设计模式,用于提供一个创建一系列相关或相互依赖对象的接口,而无需指定...
在实现报警系统时,我们还需要关注以下几个关键知识点: 1. 异步编程:为了实时响应环境变化,系统可能需要使用异步编程模型,例如回调函数、事件驱动或线程池。这样可以确保在处理报警事件的同时,不影响其他任务...
动态代理的几种方式 HashMap的并发问题 了解LinkedHashMap的应用吗 反射的原理,反射创建类实例的三种方式是什么? cloneable接口实现原理,浅拷贝or深拷贝 Java NIO使用 hashtable和hashmap的区别及实现原理,...
在Intel的这个线程池示例中,我们可能会看到以下几个关键知识点: 1. **线程池概念**:线程池是由一组工作线程组成的集合,这些线程预先创建并保持在池中,等待执行任务。当有新的任务提交时,线程池会从可用线程中...
通过深入理解ACE的进程算法技术,并结合"分光计"的实际应用,开发者可以构建出高效、可靠的系统,实现对光谱数据的精确控制和分析。这种技术的应用不仅限于分光计,还可以推广到其他需要实时数据处理和并发控制的...
ACE的核心算法可能包含以下几个关键部分: 1. **事件驱动模型**:ACE采用事件驱动的编程模型,允许程序对各种异步事件作出响应,如网络连接、数据接收等。这种模型有助于提高系统的并发处理能力和响应速度。 2. **...
流控是Sentinel三大核心能力之一,下面将详细介绍Sentinel使用的几种常见限流算法,并结合给定文件的内容进行详细分析。 限流算法是流量控制的核心,它能够有效防止系统的超载,保护系统稳定运行。常见的限流算法有...
RC4(Rivest Cipher 4)是一种流式加密算法,由Ron Rivest于1987年设计,广泛用于数据保护,如网络通信、文件加密等。而多线程则是Java中的一个核心特性,它允许程序同时执行多个任务,提高系统资源利用率,优化性能...
1. **线程池(Threadpool)**:线程池是一种多线程编程的设计模式,它预先创建了一组线程,当有任务需要执行时,不再直接创建新线程,而是从线程池中取出一个闲置的线程来执行任务。这样可以减少线程创建和销毁的...
相关性算法通常是基于TF-IDF(词频-逆文档频率)或其他更复杂的模型,Java可以通过计算库实现这些算法。 5. **文件处理**:搜索引擎可能需要处理大量数据,这涉及到文件系统的操作,如读写文件。Java的I/O流 API ...
通过对网络爬虫技术、SpringBoot框架、Java线程池等相关技术的研究与应用,成功实现了高效的数据获取与处理流程,为用户提供了一个实用的美食推荐平台。该项目不仅满足了用户对于美食信息的获取需求,还为管理员提供...
在Java中,实现多线程主要有以下几种方式: 1. 继承Thread类:创建一个Thread类的子类,并重写run()方法。 2. 实现Runnable接口:创建一个实现了Runnable接口的类,实现run()方法,并将这个类的实例作为参数传递给...