对象池框架 commons pool2 原理与实践

news/2025/3/10 15:09:01/文章来源:https://www.cnblogs.com/makemylife/p/18686809

当资源对象的创建/销毁比较耗时的场景下,可以通过"池化"技术,达到资源的复用,以此来减少系统的开销、增大系统吞吐量,比如数据库连接池、线程池、Redis 连接池等都是使用的该方式。

Apache Commons Pool 提供了通用对象池的实现,用于管理和复用对象,以提高系统的性能和资源利用率。

1 基础用法

1.1 添加依赖

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.0</version>
</dependency>

1.2 定义对象工厂

PooledObjectFactory 是一个池化对象工厂接口,定义了生成对象、激活对象、钝化对象、销毁对象的方法,如下:

public interface PooledObjectFactory<T> {/*** Creates an instance that can be served by the pool and wrap it in a*/PooledObject<T> makeObject() throws Exception;/*** Destroys an instance no longer needed by the pool*/void destroyObject(PooledObject<T> p) throws Exception;/*** Ensures that the instance is safe to be returned by the pool*/boolean validateObject(PooledObject<T> p);/*** Reinitializes an instance to be returned by the pool*/void activateObject(PooledObject<T> p) throws Exception;/*** Uninitializes an instance to be returned to the idle object pool*/void passivateObject(PooledObject<T> p) throws Exception;
}

以下是一个简单的示例:

  1. 定义需要池化的对象 MyObject
public class MyObject {private String uid = UUID.randomUUID().toString();private volatile boolean valid = true;public void initialize() {System.out.println("初始化对象" + uid);valid = true;}public void destroy() {System.out.println("销毁对象" + uid);valid = false;}public boolean isValid() {return valid;}public String getUid() {return uid;}}
  1. 定义对象工厂
public class MyObjectFactory implements PooledObjectFactory<MyObject> {@Overridepublic PooledObject<MyObject> makeObject() throws Exception {// 创建一个新对象MyObject object = new MyObject();// 初始化对象object.initialize();return new DefaultPooledObject<>(object);}@Overridepublic void destroyObject(PooledObject<MyObject> p) throws Exception {// 销毁对象p.getObject().destroy();}@Overridepublic boolean validateObject(PooledObject<MyObject> p) {return p.getObject().isValid();}@Overridepublic void activateObject(PooledObject<MyObject> p) throws Exception {}@Overridepublic void passivateObject(PooledObject<MyObject> p) throws Exception {}}

1.3 配置对象池

创建 GenericObjectPool 对象,并设置相关参数,如最大对象数量、最小空闲对象数量等。

GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxTotal(20);
config.setMaxIdle(5);
config.setTestWhileIdle(true);
config.setMinEvictableIdleTimeMillis(60000L);
GenericObjectPool<MyObject> pool = new GenericObjectPool<>(new MyObjectFactory(), config);

1.4 借用和归还对象

MyObject myObject = null;
try {myObject = pool.borrowObject();System.out.println("get对象" + myObject.getUid() +  " thread:" + Thread.*currentThread*().getName());
} catch (Exception e) {e.printStackTrace();
} finally {try {if (myObject != null) {pool.returnObject(myObject);}} catch (Exception e) {e.printStackTrace();}
}

2 Jedis 连接池

Jedis 是一个 Java 语言的 Redis 客户端库。它提供了一组易于使用的 API,可以用来连接和操作 Redis 数据库。

它的内部使用 Commons Pool 来管理 Redis 连接 ,我们使用 jedis 3.3.0 版本写一个简单的示例。

public class JedisMain {public static void main(String[] args) throws Exception{// 创建连接池配置JedisPoolConfig config = new JedisPoolConfig();config.setMaxTotal(100);config.setMaxIdle(20);// 创建连接池JedisPool pool = new JedisPool(config, "localhost", 6379);// 获取连接Jedis jedis = pool.getResource();jedis.set("hello" , "张勇");// 使用连接String value = jedis.get("hello");System.out.println(value);// 归还连接jedis.close();// 关闭连接池// pool.close();Thread.sleep(5000);}
}

如下图,JedisFactory 实现了对象工厂,实现了创建对象销毁对象验证对象激活对象四个方法。

比如验证对象方法,逻辑是调用 Jedis 的 ping 方法,判断该连接是否存活。

3 原理解析

我们重点解析 GenericObjectPool 类的原理。

3.1 初始化

public GenericObjectPool(final PooledObjectFactory<T> factory,final GenericObjectPoolConfig<T> config) {super(config, ONAME_BASE, config.getJmxNamePrefix());if (factory == null) {jmxUnregister(); // tidy upthrow new IllegalArgumentException("factory may not be null");}this.factory = factory;idleObjects = new LinkedBlockingDeque<>(config.getFairness());setConfig(config);}private final Map<IdentityWrapper<T>, PooledObject<T>> allObjects =new ConcurrentHashMap<>();

初始化做三件事情:

  1. 初始化 JedisFactory 工厂对象。

  2. 对象容器 idleObjects , 类型是 LinkedBlockingDeque

    因此存储容器有两个,所有的对象 allObjects 和空闲对象 idleObjects (可以直接取出使用)。

  3. 配置对象池属性 。

3.2 创建对象

我们关注 GenericObjectPool 类的 borrowObject 方法。

逻辑其实很简单 :

  1. 从容器中获取第一个条目对象,若没有获取,则调用工厂对象的创建对象方法,并将该对象加入到全局对象 Map。

  2. 创建成功后,调用对象的激活方法,接着验证对象的可靠性,最后将对象返回。

3.3 归还连接

流程如下:

  1. 判断返还对象时是否校验,假如校验失败,则销毁该对象,将该对象从存储容器中删除 ;
  2. 调用工厂对象的激活对象方法 ;
  3. 若空闲对象 Map 元素大小达到最大值,则销毁该对象,将该对象从存储容器中删除 ;
  4. 正常将对象放回到空闲对象容器 idleObjects

参考资料:

https://github.com/redis/jedis/wiki/Getting-started

https://github.com/apache/commons-pool

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

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

相关文章

20252025临沂一中强基考试游记

大烂特烂,故作此篇。 友情出演:王茂 *:八下年级rk1、常年年级前五 范明 *:实力不详,遇强则强,比我水平高 张晨 *:考过全区rk1,磕头 公续 *、刘子 *:仅次于王张的大神 韩梓 *:六边形战士 张嘉 *、左世 *:实力不是很清楚( 比我强就对了Day -2 被我妈施压了,说是考不…

【大厂文章学习】合并编译的学习与思考

合并编译通过将微服务的远程调用优化为本地函数调用,显著降低CPU开销和容器资源需求,但需权衡服务隔离、版本管理等挑战,适用于资源密集、调用关系紧密的场景。【大厂文章学习】合并编译的学习与思考【微信文章】字节跳动合并编译实践通过将微服务转换为本地函数调用的方式优…

安全帽识别摄像机

安全帽识别摄像机在建筑工地安全管理中具有重要意义。在高空作业、机械作业等危险环境下,佩戴安全帽是保障工人生命安全的重要措施。通过部署这种设备,系统可以实时监测工地内的作业人员,并自动识别出未佩戴安全帽的情况,及时发送警报通知现场管理人员进行处理,有效预防事…

监狱视频监控行为智能预警系统

监狱视频监控行为智能预警系统通过在监狱围墙、监舍、走廊、习艺楼等区域部署摄像机,监狱视频监控行为智能预警系统实现了对监狱内部的全方位、全天候监测。系统对连续的行为动作进行有效判断精准识别出离床、攀高、独处、倒地、斗殴、徘徊、滞留、逆行、聚众、静坐不动、入厕…

Spring-AOP(面向切面编程)

Spring-AOP(面向切面编程)面向切面编程(Aspect Oriented Programming-AOP)是面向对象编程(Object Oriented Programming-OOP)的一种补充,二者是互补的编程范式。在OOP中,关键单元是类,而在AOP中关键单元则是横切关注点。面向对象编程关注于将现实世界中的实体抽象为对象,并…

Java的控制流程

Java的控制流程 1. Scanner对象Java.util.Scanner 是Java5的新特性,我们可以通过Scanner类来获取用户的输入。 基本语法: Scanner s = new Scanner(System.in); 通过Scanner类的next() 与nextLine()方法获取输入的字符串,在读取我们一般需要 使用 hasNext() 与 hasNextLine…

【Java安全】基础汇总

一、JAVA安全 1.1 java的序列化和反序列化 Java 序列化是指把 Java 对象转换为字节序列的过程ObjectOutputStream类的 writeObject() 方法可以实现序列化 Java 反序列化是指把字节序列恢复为 Java 对象的过程ObjectInputStream 类的 readObject() 方法用于反序列化。 1、序列化…

云计算和服务器

一、云计算概述 ICT是世界电信协会在2001年的全球性会议上提出的综合性概念,ICT分为IT和CT,IT(information technology)信息技术,负责对数据生命周期的管理;CT(communication technology),负责数据的传输管理。 CT技术是ICT技术栈的底核。 1、计算机 计算机是现代一种…

movfuscator学习

demovfuscator docker镜像 - 狗小剩就是利用32位mov的图灵完备性,来代替各种代码(32位汇编太逆天了).如果看到只有mov就知道是这b玩意了,不过这种程序性能肯定不行,代码段也好长.可以利用ida查锁定字节码的范围,查相应的字符串. demovfuscator问题太多了,一个是识别c的代码无法…

中考英语优秀范文-016 How to keep a good relationship with parents 如何与父母保持良好的关系

1 写作要求 某英文报社正就青少年与父母关系这一话题开展题为“How to keep a good relationship with parents”的征文活动。请你根据以下要点, 写一篇80个词左右的英语短文参加此次活动: 1 父母规矩太多, 过于强调学习成绩, 不理解自己等问题; 2 你对这些问题的看法; 3 你与父…

KubeSphere 开源社区 2024 年度回顾与致谢

随着 2024 年圆满落幕,我们回顾 KubeSphere 社区这一年走过的每一步,感慨万千。2024 年,KubeSphere 继续领跑云原生技术的创新与发展,推动开源文化的传播,致力于为全球开发者和企业用户提供更强大的平台和解决方案。感谢每一位社区成员的辛勤付出,正是因为你们的共同努力…

云--什么是云

https://whatiscloud.com/