apache.commons.pool2 使用指南
apache.commons.pool2 使用指南
为什么要使用池
创建对象耗时较长,多线程频繁调用等因素限制了我们不能每次使用时都重新创建对象,使用池化思想将对象放进池内,不同线程使用同一个池来获取对象,极大的减少每次业务的调用时间。
一个线程内多次使用这个对象所建立的连接。
使用场景
- 数据库连接池:HikariCP、Druid
- 自定义业务连接池:耗时的客户端连接远程服务端
如何使用
1、创建对象客户端
package com.ncst.client.mcc;import lombok.extern.slf4j.Slf4j;
import java.util.Objects;/*** @Author: Lisy* @Description: MCC 操作工具类*/
@Slf4j
public class MccClient {public MccClient() {}public void putMc(String key, String value) {if (Objects.isNull(key)) {throw new IllegalArgumentException("The key argument cannot be null");}log.info("{}=={}", key, value);}public String getMc(String key) {if (Objects.isNull(key)) {throw new IllegalArgumentException("The " + key + " argument cannot be null");}return "";}}
2、创建池工厂类
package com.ncst.client.mcc;import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;/*** @Author: Lisy* @Description: 对象池工厂*/
public class MccClientFactory implements PooledObjectFactory<MccClient> {public MccClientFactory() {}@Overridepublic PooledObject<MccClient> makeObject() {MccClient dccClient = new MccClient();return new DefaultPooledObject<>(dccClient);}@Overridepublic void destroyObject(PooledObject<MccClient> p) {MccClient object = p.getObject();object.close();}@Overridepublic boolean validateObject(PooledObject<MccClient> p) {// 验证对象是否可用的逻辑,如果需要return true;}@Overridepublic void activateObject(PooledObject<MccClient> p) {// 激活对象的逻辑,如果需要}@Overridepublic void passivateObject(PooledObject<MccClient> p) {// 钝化对象的逻辑,如果需要}}
3、对象池管理类
用于管理保存的池对象,单例模式
shutdown 方法在不使用时关闭掉对应任务的所有池连接
package com.ncst.client;import com.ncst.client.mcc.MccClient;
import com.ncst.client.mcc.MccClientFactory;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;/*** @Author: Lisy* @Description: 对象池管理*/
public class MccClientPoolManager {private static volatile MccClientPoolManager INSTANCE;private MccClientPoolManager() {}public static MccClientPoolManager getInstance() {if (Objects.isNull(INSTANCE)) {synchronized (MccClientPoolManager.class) {if (Objects.isNull(INSTANCE)) {INSTANCE = new MccClientPoolManager();}}}return INSTANCE;}/*** key-jobUuid, value-每一个任务池*/private final ConcurrentHashMap<String, GenericObjectPool<MccClient>> POOL_MAP = new ConcurrentHashMap<>();public GenericObjectPool<MccClient> getPool(String jobId, GenericObjectPoolConfig<MccClient> poolConfig) {return POOL_MAP.computeIfAbsent(jobId, k -> new GenericObjectPool<>(new MccClientFactory(), poolConfig));}public void shutdown(String jobId) {GenericObjectPool<MccClient> dccClientGenericObjectPool = POOL_MAP.get(jobId);if (Objects.nonNull(dccClientGenericObjectPool)) {dccClientGenericObjectPool.close();}}
}
4、使用
通过多线程来模拟实际使用场景,如果使用默认poolConfig,那么最大池大小为8个,最多创建8个对象。
通过CountDownLatch 来等待所有任务完成
通过 MccClientPoolManager.getInstance().shutdown(“key”); 来关闭池
“key” 可根据业务逻辑自行定义
public static void main(String[] args) throws InterruptedException {int num = 20;CountDownLatch latch = new CountDownLatch(num);for (int i = 0; i < num; i++) {int finalI = i;CompletableFuture.runAsync(() -> {try {GenericObjectPool<MccClient> pool2 = MccClientPoolManager.getInstance().getPool("key", new GenericObjectPoolConfig<>());MccClient mccClient = null;try {mccClient = pool2.borrowObject();mccClient.putMc("" + finalI, "value" + finalI);} finally {if (Objects.nonNull(mccClient)) {pool2.returnObject(mccClient);}}} catch (Exception e) {logger.error(e.getMessage(), e);} finally {latch.countDown();}});}latch.await();MccClientPoolManager.getInstance().shutdown("key");}
源码解析-create()
510:private PooledObject<T> create() throws Exception
创建对象时锁住makeObjectCountLock,判断当前已创建对象是否大于设置的池大小,如果未超过则create==true超过则判断已有的池大小是否为0,如果为0返回create==false,
不为0等待正在创建的对象,执行makeObjectCountLock.waitcreate 为true则创建对象,执行 public PooledObject<T> makeObject()创建完对象后判断是否为空,如果为空将已创建对象 cretaeCount--,并抛出异常验证对象是否可用,如果不可用返回null,并cretaeCount--在finally 中锁住 makeObjectCount lock,将makeObjectCount--,唤醒锁中所有等待的对象将对象放入allObjects map中
相关文章:
apache.commons.pool2 使用指南
apache.commons.pool2 使用指南 为什么要使用池 创建对象耗时较长,多线程频繁调用等因素限制了我们不能每次使用时都重新创建对象,使用池化思想将对象放进池内,不同线程使用同一个池来获取对象,极大的减少每次业务的调用时间。 …...
【Python面试题收录】Python编程基础练习题②(数据类型+文件操作+时间操作)
本文所有代码打包在Gitee仓库中https://gitee.com/wx114/Python-Interview-Questions 一、数据类型 第一题 编写一个函数,实现:先去除左右空白符,自动检测输入的数据类型,如果是整数就转换成二进制形式并返回出结果;…...
typescript 定义类型
type infoType string; let name: infoType "全易"; let location: infoType "北京"; // let age: infoType 18; // 报错 infoType string|number 就不报错了 let job: infoType "开发"; let love: infoType "吃喝玩乐&q…...
基于Java+SpringBoot+Vue的的课程作业管理系统
前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 哈喽兄弟们,好久不见哦࿵…...
分布式日志分析系统--ELK
文章目录 ELK概述ELK主要特点ELK应用架构 Elasticsearch原理JSON格式倒排索引 ES与关系型数据库ES相关概念ES安装说明1.环境初始化2.优化系统资源限制配置3.编辑ES服务文件elasticsearch. yml 优化ELK集群安装脚本scp的使用集群安装成功 Shell命令API使用创建索引创建Type创建分…...
Linux初学基本命令
linux文件目录 1、bin->usr/bin binary存放命令 所有账户可以使用 Linux可以执行的文件,我们称之为命令command 2、boot 存放系统启动文件 3、dev device存放设备文件 4、etc 存放配置文件的目录 configration files 5、home home家目录 存…...
如何优化PyTorch以加快模型训练速度?
PyTorch是当今生产环境中最流行的深度学习框架之一。随着模型变得日益复杂、数据集日益庞大,优化模型训练性能对于缩短训练时间和提高生产力变得至关重要。 本文将分享几个最新的性能调优技巧,以加速跨领域的机器学习模型的训练。这些技巧对任何想要使用…...
用最简单的方法对大数据进行处理 vs spark(不需要安装大数据处理工具)
一、大文件处理策略 (一)、难点 内存管理: 大文件无法一次性加载到内存中,因为这可能会导致内存溢出(OutOfMemoryError)。 因此,需要使用流(Stream)或缓冲区(…...
非线性校正算法在红外测温中的应用
非线性校正算法在红外测温中用于修正传感器输出与实际温度之间的非线性关系。红外传感器的输出信号(通常是电压或电流)与温度的关系理论上是线性的,但在实际应用中,由于传感器特性的限制,这种关系往往呈现出非线性。非…...
python----线程、进程、协程的区别及多线程详解
文章目录 一、线程、进程、协程区别二、创建线程1、函数创建2、类创建 三、线程锁1、Lock2、死锁2.1加锁之后处理业务逻辑,在释放锁之前抛出异常,这时的锁没有正常释放,当前的线程因为异常终止了,就会产生死锁。2.2开启两个或两个…...
将 magma example 改写成 cusolver example eqrf
1,简单安装Magma 1.1 下载编译 OpenBLAS $ git clone https://github.com/OpenMathLib/OpenBLAS.git $ cd OpenBLAS/ $ make -j DEBUG1 $ make install PREFIX/home/hipper/ex_magma/local_d/OpenBLAS/1.2 下载编译 magma $ git clone https://bitbucket.org/icl…...
微信小程序教程007:数据绑定
文章目录 数据绑定1、数据绑定原则2、在data中定义页面数据3、Mustache语法的格式4、Mustache应用场景5、绑定属性6、三元运算8、算数运算数据绑定 1、数据绑定原则 在data中定义数据在WXML中使用数据2、在data中定义页面数据 在页面对应的.js文件中,把数据定义到data对象中…...
Git -- git stash 暂存
使用 git 或多或少都会了解到 git stash 命令,但是可能未曾经常使用,下面简单介绍两种使用场景。 场景一:分支A开发,分支B解决bug 我们遇到最常见的例子就是,在当前分支 A 上开发写需求,但是 B 分支上有…...
基于YOLO的植物病害识别系统:从训练到部署全攻略
基于深度学习的植物叶片病害识别系统(UI界面YOLOv8/v7/v6/v5代码训练数据集) 1. 引言 在农业生产中,植物叶片病害是影响作物产量和质量的主要因素之一。传统的病害检测方法依赖于人工识别,效率低且易受主观因素影响。随着深度学…...
数据库开发:MySQL基础(二)
MySQL基础(二) 一、表的关联关系 在关系型数据库中,表之间可以通过关联关系进行连接和查询。关联关系是指两个或多个表之间的关系,通过共享相同的列或键来建立连接。常见的关联关系有三种类型:一对多关系,…...
实现物理数据库迁移到云上
实现物理数据库迁移到云上 以下是一个PHP脚本,用于实现物理数据库迁移到云上的步骤: <?php// 评估和规划 $databaseSize "100GB"; $performanceRequirements "high"; $dataComplexity "medium";$cloudProvider &…...
[Spring] MyBatis操作数据库(进阶)
🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…...
【Websim.ai】一句话让AI帮你生成一个网页
【Websim.ai】一句话让AI帮你生成一个网页 网站链接 websim.ai 简介 websim.ai接入了Claude Sonnet 3.5,GPT-4o等常用的LLM,只需要在websim.ai的官网指令栏中编写相关指令,有点类似大模型的Prompt,指令的好坏决定了网页生成的…...
云计算实训16——关于web,http协议,https协议,apache,nginx的学习与认知
一、web基本概念和常识 1.Web Web 服务是动态的、可交互的、跨平台的和图形化的为⽤户提供的⼀种在互联⽹上浏览信息的服务。 2.web服务器(web server) 也称HTTP服务器(HTTP server),主要有 Nginx、Apache、Tomcat 等。…...
2024年必备技能:小红书笔记评论自动采集,零基础也能学会的方法
摘要: 面对信息爆炸的2024年,小红书作为热门社交平台,其笔记评论成为市场洞察的金矿。本文将手把手教你,即便编程零基础,也能轻松学会利用Python自动化采集小红书笔记评论,解锁营销新策略,提升…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
倒装芯片凸点成型工艺
UBM(Under Bump Metallization)与Bump(焊球)形成工艺流程。我们可以将整张流程图分为三大阶段来理解: 🔧 一、UBM(Under Bump Metallization)工艺流程(黄色区域ÿ…...
数据分析六部曲?
引言 上一章我们说到了数据分析六部曲,何谓六部曲呢? 其实啊,数据分析没那么难,只要掌握了下面这六个步骤,也就是数据分析六部曲,就算你是个啥都不懂的小白,也能慢慢上手做数据分析啦。 第一…...
理想汽车5月交付40856辆,同比增长16.7%
6月1日,理想汽车官方宣布,5月交付新车40856辆,同比增长16.7%。截至2025年5月31日,理想汽车历史累计交付量为1301531辆。 官方表示,理想L系列智能焕新版在5月正式发布,全系产品力有显著的提升,每…...
