池化技术到达有多牛?看了线程和线程池的对比吓我一跳!

这是我的第 82 篇原创文章

作者 | 王磊

来源 | Java中文社群(ID:javacn666)

转载请联系授权(微信ID:GG_Stone)

情商高的人是能洞察并照顾到身边所有人的情绪,而好的文章应该让所有人都能看懂。

尼采曾经说过:人们无法理解他没有经历过的事情。因此我会试着把技术文章写的尽量具象化一些,力求让所有人都能看懂,所以在正式开始之前,我们先从两个生活事例说起。

尼采帅照:

唠嗑:之前一直以为尼采是中国的某位圣人,大体和庄子差不多,后来才知道原来是一位老外,惊了个呆。

生活案例 1

早些年间,某宝双“11”突然爆火,然后无数个男男女女疯狂“剁手”,然而最痛苦的并不是“剁手”之后吃“灰”的日子,而是漫长而又揪心的等待快递小哥的日子。

为了缓解彼此的“痛苦”(快递公司的电话被打爆,用户等得不耐烦),快递公司后面就变“聪明”了,每当购物节将要来临之前,快递公司会预先准备好充足的人和车,以迎接扑面而来的订单。

至此,当我们再遇到各种购物节,就再也不用每天盯着手机煎熬的等待快递小哥了。

生活案例 2

小美是一家公司的 HR,每年年初是小美最头疼的日子了。因为年初有大量的员工离职,因此小美需要一边办理离职员工的手续,一边疯狂的招人,除了这些工作之外,小美还要忍受来自各部门和大 BOSS 的间歇性催促,这些都让小美痛苦不已。

于是为了应对每年年初的这种囧境,小美也变聪明了,她每年年末的时候都会预先招聘一些员工,以备来年的不时之需。

自从用了这招之后(提前招人),小美从此过上了幸福的生活。

概念

池化技术指的是提前准备一些资源,在需要时可以重复使用这些预先准备的资源。

也就是说池化技术有两个优点:

  1. 提前创建;

  2. 重复利用。

池化技术优点分析

以 Java 中的对象创建来说,在对象创建时要经历以下步骤:

  1. 根据 new 标识符后面的参数,在常量池查找类的符号引用;

  2. 如果没找到符号应用(类并未加载),进行类的加载、解析、初始化等;

  3. 虚拟机为对象在堆中分配内存,并将分配的内存初始化为 0,针对对象头,建立相应的描述结构(耗时操作:需要查找堆中的空闲区域,修改内存分配状态等);

  4. 调用对象的初始化方法(耗时操作:用户的复杂的逻辑验证等操作,如IO、数值计算是否符合规定等)。

从上述的流程中可以看出,创建一个类需要经历复杂且耗时的操作,因此我们应该尽量复用已有的类,以确保程序的高效运行,当然如果能够提前创建这些类就再好不过了,而这些功能都可以用池化技术来实现

池化技术常见应用

常见的池化技术的使用有:线程池、内存池、数据库连接池、HttpClient 连接池等,下面分别来看。

1.线程池

线程池的原理很简单,类似于操作系统中的缓冲区的概念。线程池中会先启动若干数量的线程,这些线程都处于睡眠状态。当客户端有一个新的请求时,就会唤醒线程池中的某一个睡眠的线程,让它来处理客户端的这个请求,当处理完这个请求之后,线程又处于睡眠的状态。

线程池能很高地提升程序的性能。比如有一个省级数据大集中的银行网络中心,高峰期每秒的客户端请求并发数超过100,如果为每个客户端请求创建一个新的线程的话,那耗费的 CPU 时间和内存都是十分惊人的,如果采用一个拥有 200 个线程的线程池,那将会节约大量的系统资源,使得更多的 CPU 时间和内存用来处理实际的商业应用,而不是频繁的线程创建和销毁。


2.内存池

如何更好地管理应用程序内存的使用,同时提高内存使用的频率,这时值得每一个开发人员深思的问题。内存池(Memory Pool)就提供了一个比较可行的解决方案。

内存池在创建的过程中,会预先分配足够大的内存,形成一个初步的内存池。然后每次用户请求内存的时候,就会返回内存池中的一块空闲的内存,并将这块内存的标志置为已使用。当内存使用完毕释放内存的时候,也不是真正地调用 free 或 delete 的过程,而是把内存放回内存池的过程,且放回的过程要把标志置为空闲。最后,应用程序结束就会将内存池销毁,将内存池中的每一块内存释放。

内存池的优点

  • 减少内存碎片的产生,这个优点可以从创建内存池的过程中看出,当我们在创建内存池的时候,分配的都是一块块比较规整的内存块,减少内存碎片的产生。

  • 提高了内存的使用频率。这个可以从分配内存和释放内存的过程中看出。每次的分配和释放并不是去调用系统提供的函数或操作符去操作实际的内存,而是在复用内存池中的内存。

内存池的缺点:会造成内存的浪费,因为要使用内存池需要在一开始分配一大块闲置的内存,而这些内存不一定全部被用到。

3.数据库连接池

数据库连接池的基本思想是在系统初始化的时候将数据库连接作为对象存储在内存中,当用户需要访问数据库的时候,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。在使用完毕后,用户也不是将连接关闭,而是将连接放回到连接池中,以供下一个请求访问使用,而这些连接的建立、断开都是由连接池自身来管理的。

同时,还可以设置连接池的参数来控制连接池中的初始连接数、连接的上下限数和每个连接的最大使用次数、最大空闲时间等。当然,也可以通过连接池自身的管理机制来监视连接的数量、使用情况等。


4.HttpClient 连接池

HttpClient 我们经常用来进行 HTTP 服务访问。我们的项目中会有一个获取任务执行状态的功能使用 HttpClient,一秒钟请求一次,经常会出现 Conection Reset 异常。经过分析发现,问题是出在 HttpClient 的每次请求都会新建一个连接,当创建连接的频率比关闭连接的频率大的时候,就会导致系统中产生大量处于 TIME_CLOSED 状态的连接,这个时候使用连接池复用连接就能解决这个问题。

实战:线程 VS 线程池

本文我们使用之前文章介绍的统计方法《6种快速统计代码执行时间的方法,真香!(史上最全)》,来测试一下线程和线程池执行的时间差距有多大,测试代码如下:

import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/*** 线程池 vs 线程 性能对比*/
public class ThreadPoolPerformance {// 最大执行次数public static final int maxCount = 1000;public static void main(String[] args) throws InterruptedException {// 线程测试代码ThreadPerformanceTest();// 线程池测试代码ThreadPoolPerformanceTest();}/*** 线程池性能测试*/private static void ThreadPoolPerformanceTest() throws InterruptedException {// 开始时间long stime = System.currentTimeMillis();// 业务代码ThreadPoolExecutor tp = new ThreadPoolExecutor(10, 10, 0,TimeUnit.SECONDS, new LinkedBlockingDeque<>());for (int i = 0; i < maxCount; i++) {tp.execute(new PerformanceRunnable());}tp.shutdown();tp.awaitTermination(1, TimeUnit.SECONDS);  // 等待线程池执行完成// 结束时间long etime = System.currentTimeMillis();// 计算执行时间System.out.printf("线程池执行时长:%d 毫秒.", (etime - stime));System.out.println();}/*** 线程性能测试*/private static void ThreadPerformanceTest() {// 开始时间long stime = System.currentTimeMillis();// 执行业务代码for (int i = 0; i < maxCount; i++) {Thread td = new Thread(new PerformanceRunnable());td.start();try {td.join(); // 确保线程执行完成} catch (InterruptedException e) {e.printStackTrace();}}// 结束时间long etime = System.currentTimeMillis();// 计算执行时间System.out.printf("线程执行时长:%d 毫秒.", (etime - stime));System.out.println();}// 业务执行类static class PerformanceRunnable implements Runnable {@Overridepublic void run() {for (int i = 0; i < maxCount; i++) {long num = i * i + i;}}}
}

以上程序的执行结果如下图所示:

为了防止执行的先后顺序影响测试结果,下面我将线程池和线程调用方法打个颠倒,执行结果如下图所示:

总结

从线程和线程池的测试结果来看,当我们使用池化技术时,程序的性能可以提升 10 倍。此测试结果并不代表池化技术的性能量化结果,因为测试结果受执行方法和循环次数的影响,但巨大的性能差异足以说明池化技术的优势所在

无独有偶,阿里巴巴的《Java开发手册》中也强制规定「线程资源必须通过线程池提供,不允许在应用中自行显式创建线程」规定如下:

因此掌握并使用池化技术是一个合格程序员的标配,你还知道哪些常用的池化技术吗?欢迎评论区留言补充。

参考 & 引用

https://zhuanlan.zhihu.com/p/32204303

https://www.cnblogs.com/yanggb/p/10632317.html

最后的话原创不易,都看到这了,点个「赞」再走呗,这是对我最大的支持与鼓励,谢谢你!往期推荐

6种快速统计代码执行时间的方法,真香!(史上最全)


最简单的6种防止数据重复提交的方法!(干货)

关注下方二维码,每一天都有干货!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/545991.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spearman相关性_Spearman的相关性及其在机器学习中的意义

spearman相关性This article is about correlation and its implication in the machine learning. In my previous article, I have discussed Pearson’s correlation coefficient and later we have written a code to show the usefulness of finding Pearson’s correlati…

被问哭了,一位小姐姐的阿里面经!(附部分答案)

这篇文章是一位 女读者 &#xff08;加粗&#xff01;太难得&#xff09;的面试阿里的经历分享&#xff0c;虽然第二面就失败了&#xff0c;但是这样的经历对自己帮助应该还是很大的。下面的一些问题非常具有代表性&#xff0c;部分问题我简单做了修改&#xff08;有些问题表述…

阿里《Java开发手册》最新嵩山版发布!

《Java 开发手册》是阿里巴巴集团技术团队的集体智慧结晶和经验总结&#xff0c;经历了多次大规模一线实战的检验及不断完善&#xff0c;公开到业界后&#xff0c;众多社区开发者踊跃参与&#xff0c;共同打磨完善&#xff0c;系统化地整理成册&#xff0c;当前的版本是嵩山版。…

递归转化成非递归过程_8086微处理器中的递归和重入过程

递归转化成非递归过程As we all know that a procedure is a set of instruction written separately which can be used any time in the code when required. A normal procedure execution includes calling of the procedure, shifting the control of the processor to th…

漫谈软件研发特种部队之中的一个

特种部队&#xff0c;是指进行特殊任务的部队&#xff0c;具有编制灵活、人员精干、装备精良、机动高速、训练有素、战斗力强等特点。 特种部队最早出如今二战期间。德国于1939年9月1日的波兰战役中首次投入了一种被称为“勃兰登堡”部队的特种部队作为德国突击波兰的先锋&…

不要一把梭了,这才是SQL优化的正确姿势!|原创干货

这是我的第 83 篇原创文章作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;年少不知优化苦&#xff0c;遇坑方知优化难。——村口王大爷全文内容预览&#xff1a;我之前有很多…

PLSQL_性能优化系列10_Oracle Array数据组优化

2014-09-25 Created By BaoXinjian 一、摘要 集合是Oracle开发中经常遇到的情况&#xff0c;Oracle集合分为三种情况&#xff1a;索引表集合(index by table)、嵌套表集合(nested table)、可变集合(varry table)。 PL/SQL中没有数组的概念&#xff0c;他的集合数据类型和数组是…

IDEA 2020.2 重磅发布,动画级新功能预览!

Guide 关注了 IDEA 的官推&#xff0c;平时没事就会去看看有没有啥比较好的更新。今天下午看到IntelliJ IDEA 2020.2 都已经发布并且还支持了 Java15。然后&#xff0c;我就去官网简单看了一下新特性。单看新特性&#xff0c;这个新版本还是有一点香的。虽然我还木有升级到这个…

访问控制模型ACL和RBAC

2019独角兽企业重金招聘Python工程师标准>>> 1.ACL ACL是最早也是最基本的一种访问控制机制&#xff0c;它的原理非常简单&#xff1a;每一项资源&#xff0c;都配有一个列表&#xff0c;这个列表记录的就是哪些用户可以对这项资源执行CRUD中的那些操作。当系统试图…

最常见并发面试题整理!(速度收藏)

前言并发编程是面试中必问的知识点之一&#xff0c;所以本文整理了一些最为常见的并发面试题&#xff0c;一起来看吧~1. synchronized的实现原理以及锁优化&#xff1f;synchronized的实现原理synchronized作用于「方法」或者「代码块」&#xff0c;保证被修饰的代码在同一时间…

JavaScript中的嵌套事件处理(在鼠标移动事件上)

Multiple event handling is the secret ingredient of dynamic WebPages seen now-a-days. 多重事件处理是当今动态网页的秘密组成部分。 Now, let’s get started... 现在&#xff0c;让我们开始吧... Example Code 范例程式码 <html lang"en"><head&…

皮尔逊相关性_皮尔逊的相关性及其在机器学习中的意义

皮尔逊相关性Today we would be using a statistical concept i.e. Pearsons correlation to help us understand the relationships between the feature values (independent values) and the target value (dependent value or the value to be predicted ) which will furt…

磊哥最近面试了好多人,聊聊我的感受!(附面试知识点)

这是我的第 84 篇原创文章作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;一些读者可能知道&#xff0c;磊哥前段时间又回来上班了&#xff0c;详见《磊哥又滚回职场了...》…

M4 宏处理器

2019独角兽企业重金招聘Python工程师标准>>> M4 宏处理器 Brian W. KernighanDennis M. Ritchie Bell LaboratoriesMurray Hill, New Jersey 07974 翻译&#xff1a;寒蝉退士 译者声明&#xff1a;译者对译文不做任何担保&#xff0c;译者对译文不拥有任何权利并且不…

绝了,几款主流的 JSON 库性能对比!

本篇通过JMH&#xff08;Oracle官方测试框架&#xff09;来测试一下Java中几种常见的JSON解析库的性能。每次都在网上看到别人说什么某某库性能是如何如何的好&#xff0c;碾压其他的库。但是百闻不如一见&#xff0c;只有自己亲手测试过的才是最值得相信的。JSON不管是在Web开…

DWZ使用笔记

DWZ使用笔记 一、前言 在近期的一个项目中&#xff0c;引入了DWZ这个富client框架&#xff0c;算是一次尝试吧。期间也遇到不少问题&#xff0c;总算一一攻克了。特以此文记之。本人用的是dwz-ria-1.4.5Asp.net webform&#xff0c;写这篇笔记时最新版本号已经是1.4.6了。DWZ官…

阿里的简历多久可以投递一次?次数多了有没有影响?可以同时进行吗?

最近&#xff0c;无论是读者群&#xff0c;还是公众号后台&#xff0c;很多人都比较关注以下几个问题&#xff1a;阿里的简历是半年只能投递一次吗&#xff1f;阿里的面试可以多个部门同时进行吗&#xff1f;面试没过&#xff0c;又被系统捞起来了&#xff0c;我该怎么办&#…

记一次蚂蚁金服面试被虐经历

本文来自作者投稿&#xff0c;原作者&#xff1a;yes面试前的小姐姐来说说前不久蚂蚁金服一面的情况。说来也是巧合&#xff0c;当时在群里有位蚂蚁金服的小姐姐发了个内推&#xff0c;看了下JD感觉可以试试于是就私聊了小姐姐发简历内推了。我16年也就是大三上就开始实习了&am…

用python + openpyxl处理excel(07+)文档 + 一些中文处理的技巧

2019独角兽企业重金招聘Python工程师标准>>> 寻觅工具 确定任务之后第一步就是找个趁手的库来干活。 Python Excel上列出了xlrd、xlwt、xlutils这几个包&#xff0c;但是 它们都比较老&#xff0c;xlwt甚至不支持07版以后的excel它们的文档不太友好&#xff0c;都可…

Spring Boot 2.3.3 正式发布!

Spring Boot 2.3.3 稳定版已发布&#xff0c;可从 repo.spring.io 和 Maven Central 获取。<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.3.RELEASE</versio…