0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

线程池的运转流程图 池化技术实践案例解析

jf_ro2CN3Fa 来源:稀土掘金 2023-11-24 10:22 次阅读

1 一些废话

作为一名Java开发人员,池化技术或多或少在业务代码中使用。常见的包括线程池、连接池等。也是因为Java语言超级丰富的基建,基本上这些池化能力都有着相对成熟的“工具”。

比如,需要使用线程池的时候常常会选择Spring提供的 ThreadPoolTaskExecutor , 工具内部替我们维护了线程的生命周期与任务的状态变化。

线程池的运转流程图

f9c57a96-8a69-11ee-939d-92fbcf53809c.png

2 正文开始

在笔者的业务场景里,java服务需要通过命令行启动一个特殊进程,并在进程使用完后将其销毁。而业务对启动这个进程的整体耗时较为敏感,打算利用池化技术,将进程池化复用,去除启动进程的消耗,达到优化性能的目标。

f9e0251c-8a69-11ee-939d-92fbcf53809c.png

认识 GenericObjectPool

池化技术的概念大家可能都比较熟悉了,但真正要从零开始实现池化能力,就会感觉困难很多。好在Java丰富的基建在提供ThreadPoolTaskExecutor的同时,也提供了GenericObjectPool这个辅助我们实现自定义对象池化的工具。顺带提一句:JedisPool就是使用这个工具实现的。

GenericObjectPool构造方法一共就3个参数,只有PooledObjectFactory必传;

/**
*Createsanew{@codeGenericObjectPool}thattracksanddestroys
*objectsthatarecheckedout,butneverreturnedtothepool.
*
*@paramfactoryTheobjectfactorytobeusedtocreateobjectinstances
*usedbythispool
*@paramconfigThebasepoolconfigurationtouseforthispoolinstance.
*Theconfigurationisusedbyvalue.Subsequentchangesto
*theconfigurationobjectwillnotbereflectedinthe
*pool.
*@paramabandonedConfigConfigurationforabandonedobjectidentification
*andremoval.Theconfigurationisusedbyvalue.
*/
publicGenericObjectPool(finalPooledObjectFactoryfactory,
finalGenericObjectPoolConfigconfig,finalAbandonedConfigabandonedConfig){
}

PooledObjectFactory 按照方法注释的描述,它是专门负责给池子创建对象实例的。当然除了创建对象(makeObject), 还包括了检验、激活、销毁对象。基本涵盖了对象生命周期中的各个阶段。

voidactivateObject(PooledObjectp)throwsException;

voiddestroyObject(PooledObjectp)throwsException;

PooledObjectmakeObject()throwsException;

voidpassivateObject(PooledObjectp)throwsException;

booleanvalidateObject(PooledObjectp);

更加详细的说明可以浏览 GenericObjectPool's apidocs [1]。源码的注释也很详细值得一看。

使用 GenericObjectPool

先引入依赖


org.apache.commons
commons-pool2
${version}

根据自身业务实现PooledObjectFactory接口;作者的业务场景是进程池化,那么对应的创建对象、销毁对象的方法就是创建进程和销毁进程的代码。

publicclassMyProcessFactoryimplementsPooledObjectFactory{
@Override
publicvoiddestroyObject(PooledObjectp)throwsException{
finalMyProcessprocess=p.getObject();
if(null!=process){
//销毁进程
process.stop();
}
}

@Override
publicPooledObjectmakeObject()throwsException{
//这里就是去创建一个进程
MyProcessprocess=newMyProcess();
process.start();
returnnewDefaultPooledObject<>(process);
}

//剩下几个方法也可以按需实现
}

下一步就是构建 GenericObjectPool 实例

PooledObjectFactoryfactory=newMyProcessFactory();
GenericObjectPoolpool=newGenericObjectPool(factory);

使用GenericObjectPool

//获取进程实例
MyProcessprocess=pool.borrowObject();

//归还实例
pool.returnObject(process);

进阶使用 GenericObjectPoolConfig

顾名思义,GenericObjectPoolConfig是池化工具的配置类;它包含了池的最大容量、池的最大空闲数、最小空闲数等核心参数。除此之外在它的父类 BaseObjectPoolConfig 中,空闲对象检测规则,对象存放队列进出规则(LIFO)等更加细节的配置。

/**
*Thedefaultvalueforthe{@codemaxTotal}configurationattribute.
*@seeGenericObjectPool#getMaxTotal()
*/
publicstaticfinalintDEFAULT_MAX_TOTAL=8;

/**
*Thedefaultvalueforthe{@codemaxIdle}configurationattribute.
*@seeGenericObjectPool#getMaxIdle()
*/
publicstaticfinalintDEFAULT_MAX_IDLE=8;

/**
*Thedefaultvalueforthe{@codeminIdle}configurationattribute.
*@seeGenericObjectPool#getMinIdle()
*/
publicstaticfinalintDEFAULT_MIN_IDLE=0;

通过调整这些参数值,就能创建符合业务要求的池子。下面就是能常驻4个进程的一套配置参数。

privateGenericObjectPoolConfiggenericObjectPoolConfig(){
finalGenericObjectPoolConfigconfig=newGenericObjectPoolConfig<>();
config.setMaxTotal(20);//池的最大容量
config.setMaxIdle(4);//最大空闲连接数
config.setMinIdle(0);//最小空闲连接数
config.setMaxWait(Duration.ofSeconds(5));//获取对象时最大等待时间
config.setTimeBetweenEvictionRuns(Duration.ofMinutes(1));//空闲对象检查间隔
config.setMinEvictableIdleTime(Duration.ofMinutes(10));//空闲对象被移除的最小空闲时间
config.setTestOnBorrow(true);
config.setLifo(false);
returnconfig;
}

3 后续

当然真实的业务中还会有很多不相关的逻辑夹杂其中,上文基本涵盖了池化对象搭建与配置的实现方法。最终也实现了性能优化的目标。希望此文能为大家在池化运用多些帮助。

审核编辑:黄飞

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • JAVA
    +关注

    关注

    19

    文章

    2946

    浏览量

    104286
  • 编程语言
    +关注

    关注

    10

    文章

    1917

    浏览量

    34465
  • 线程池
    +关注

    关注

    0

    文章

    55

    浏览量

    6816

原文标题:池化技术在真实业务中的实践

文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Java中的线程包括哪些

    线程是用来统一管理线程的,在 Java 中创建和销毁线程都是一件消耗资源的事情,线程可以重复
    的头像 发表于 10-11 15:33 745次阅读
    Java中的<b class='flag-5'>线程</b><b class='flag-5'>池</b>包括哪些

    动态线程思想学习及实践

    相关文档 美团线程实践:https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html 线程
    的头像 发表于 06-13 15:43 1070次阅读
    动态<b class='flag-5'>线程</b><b class='flag-5'>池</b>思想学习及<b class='flag-5'>实践</b>

    买药秒送 JADE动态线程实践及原理浅析

    一、背景及JADE介绍 买药秒送是健康即时零售业务新的核心流量场域,面对京东首页高流量曝光,我们对频道页整个技术架构方案进行升级,保障接口高性能、系统高可用。 动态线程是买药频道应用的技术
    的头像 发表于 09-04 11:11 710次阅读
    买药秒送 JADE动态<b class='flag-5'>线程</b><b class='flag-5'>池</b><b class='flag-5'>实践</b>及原理浅析

    线程是如何实现的

    线程的概念是什么?线程是如何实现的?
    发表于 02-28 06:20

    基于线程技术集群接入点的应用研究

    本文在深入研究高级线程技术的基础上,分析、研究了固定线程数目的线程
    发表于 01-22 14:21 5次下载

    基于Nacos的简单动态线程实现

    本文以Nacos作为服务配置中心,以修改线程核心线程数、最大线程数为例,实现一个简单的动态线程
    发表于 01-06 14:14 793次阅读

    Spring 的线程应用

    我们在日常开发中,经常跟多线程打交道,Spring 为我们提供了一个线程方便我们开发,它就是 ThreadPoolTaskExecutor ,接下来我们就来聊聊 Spring 的线程
    的头像 发表于 10-13 10:47 542次阅读
    Spring 的<b class='flag-5'>线程</b><b class='flag-5'>池</b>应用

    什么是内存

    1什么是内存 1.1技术 所谓“技术”,就
    的头像 发表于 11-08 16:26 744次阅读
    什么是内存<b class='flag-5'>池</b>

    了解连接线程、内存、异步请求

    技术 技术能够减少资源对象的创建次数,提⾼程序的响应性能,特别是在⾼并发下这种提⾼更加明
    的头像 发表于 11-09 14:44 990次阅读
    了解连接<b class='flag-5'>池</b>、<b class='flag-5'>线程</b><b class='flag-5'>池</b>、内存<b class='flag-5'>池</b>、异步请求<b class='flag-5'>池</b>

    线程基本概念与原理

    一、线程基本概念与原理 1.1 线程概念及优势 C++线程简介
    的头像 发表于 11-10 10:24 429次阅读

    线程的基本概念

    线程的基本概念 不管线程是什么东西!但是我们必须知道线程被搞出来的目的就是:提高程序执行效
    的头像 发表于 11-10 16:37 447次阅读
    <b class='flag-5'>线程</b><b class='flag-5'>池</b>的基本概念

    技术的应用实践

    作为一名Java开发人员,技术或多或少在业务代码中使用。常见的包括线程、连接等。也是因为
    的头像 发表于 11-24 10:22 429次阅读
    <b class='flag-5'>池</b><b class='flag-5'>化</b><b class='flag-5'>技术</b>的应用<b class='flag-5'>实践</b>

    线程七大核心参数执行顺序

    线程是一种用于管理和调度线程执行的技术,通过将任务分配到线程池中的线程进行处理,可以有效地控制
    的头像 发表于 12-04 16:45 826次阅读

    线程的创建方式有几种

    线程是一种用于管理和调度线程技术,能够有效地提高系统的性能和资源利用率。它通过预先创建一组线程并维护一个工作队列,将任务提交给
    的头像 发表于 12-04 16:52 718次阅读

    什么是动态线程?动态线程的简单实现思路

    因此,动态可监控线程一种针对以上痛点开发的线程管理工具。主要可实现功能有:提供对 Spring 应用内线程
    的头像 发表于 02-28 10:42 500次阅读