科技> 正文

今日热搜:池化技术有哪些优点?池化技术常见应用有哪些?

时间: 2022-09-23 10:10:59 来源: IT专家网

最近小编看到大家都在讨论看了线程和线程池的对比,才知道池化技术到底有多牛相关的事情,对此呢小编也是非常的感应兴趣,那么这件事究竟是怎么发生的呢?具体又是怎么回事呢?下面就是小编搜索到的关于看了线程和线程池的对比,才知道池化技术到底有多牛事件的相关信息,我们一起来看一下吧!


【资料图】

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

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

生活案例 1

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

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

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

生活案例 2

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

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

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

概念

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

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

提前创建;

重复利用。

池化技术优点分析

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

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

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

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

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

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

池化技术常见应用

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

1.线程池

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

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

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 {

@Override

public void run() {

for (int i = 0; i < maxCount; i++) {

long num = i * i + i;

}

}

}

}总结

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

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

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

关键词: 一个新的 测试结果 执行时间

责任编辑:QL0009

为你推荐

关于我们| 联系我们| 投稿合作| 法律声明| 广告投放

版权所有 © 2020 跑酷财经网

所载文章、数据仅供参考,使用前务请仔细阅读网站声明。本站不作任何非法律允许范围内服务!

联系我们:315 541 185@qq.com