目录
1. 什么是对象池
2. 为什么需要对象池
3. 对象池的实现
4. 开源的对象池工具
5. JedisPool 对象池实现分析
6. 对象池总结
最近在分析一个应用中的某个接口的耗时情况时,发现一个看起来极其普通的对象创建操作,竟然每次需要消耗 8ms 左右时间,分析后发现这个对象可以通过对象池模式进行优化,优化后此步耗时仅有 0.01ms,这篇文章介绍对象池相关知识。
1. 什么是对象池
池化并不是什么新鲜的技术,它更像一种软件设计模式,主要功能是缓存一组已经初始化的对象,以供随时可以使用。对象池大多数场景下都是缓存着创建成本过高或者需要重复创建使用的对象,从池子中取对象的时间是可以预测的,但是新建一个对象的时间是不确定的。
当需要一个新对象时,就向池中借出一个,然后对象池标记当前对象正在使用,使用完毕后归还到对象池,以便再次借出。
常见的使用对象池化场景:
- 对象创建成本过高。
- 需要频繁的创建大量重复对象,会产生很多内存碎片。
- 同时使用的对象不会太多。
- 常见的具体场景如数据库连接池、线程池等。
2. 为什么需要对象池
如果一个对象的创建成本很高,比如建立数据库的连接时耗时过长,在不使用池化技术的情况下,我们的查询过程可能是这样的。
查询 1:建立数据库连接 -> 发起查询 -> 收到响应 -> 关闭连接
查询 2:建立数据库连接 -> 发起查询 -> 收到响应 -> 关闭连接
查询 3:建立数据库连接 -> 发起查询 -> 收到响应 -> 关闭连接
那么使用池化思想是怎么样的呢样的过程会转变成下面的步骤。
使用池化思想后,数据库连接并不会频繁的创建关闭,而是启动后就初始化了 N 个连接以供后续使用,使用完毕后归还对象,这样程序的总体性能得到提升。
3. 对象池的实现
通过上面的例子也可以发现池化思想的几个关键步骤:初始化、借出、归还。上面没有展示销毁步骤, 某些场景下还需要对象的销毁这一过程,比如释放连接。
下面我们手动实现一个简陋的对象池,加深下对对象池的理解。主要是定一个对象池管理类,然后在里面实现对象的初始化、借出、归还、销毁等操作。
代码还是比较简单的,只是简单的示例,下面我们通过池化一个 Redis 连接对象 Jedis 来演示如何使用。
其实 Jedis 中已经有对应的 Jedis 池化管理对象了 JedisPool 了,不过我们这里为了演示对象池的实现,就不使用官方提供的 JedisPool 了。
启动一个 Redis 服务这里不做介绍,假设你已经有了一个 Redis 服务,下面引入 Java 中连接 Redis 需要用到的 Maven 依赖。
正常情况下 Jedis 对象的使用方式:
如果使用上面的对象池,就可以像下面这样使用。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!