commons.pool2 对象池的使用
commons.pool2 对象池的使用
1
2
3
4
5
|
< dependency >
< groupId >org.apache.commons</ groupId >
< artifactId >commons-pool2</ artifactId >
< version >2.3</ version >
</ dependency >
|
池对象工厂 PooledObjectFactory和池对象 DefaultPooledObject
先了解个概念:
池对象工厂(PooledObjectFactory接口):用来创建池对象, 将不用的池对象进行钝化(passivateObject), 对要使用的池对象进行激活(activeObject), 对池对象进行验证(validateObject), 对有问题的池对象进行销毁(destroyObject)等工作
PooledObjectFactory是一个池化对象工厂接口,定义了生成对象、激活对象、钝化对象、销毁对象的方法,如下
1
2
3
4
5
6
7
8
9
10
11
|
public interface PooledObjectFactory< T > {
PooledObject< T > makeObject() throws Exception;
void destroyObject(PooledObject< T > var1) throws Exception;
boolean validateObject(PooledObject< T > var1);
void activateObject(PooledObject< T > var1) throws Exception;
void passivateObject(PooledObject< T > var1) throws Exception;
}
|
如果需要使用Commons-Pool,那么你就需要提供一个PooledObjectFactory接口的具体实现。一个比较简单的办法就是,继承BasePooledObjectFactory这个抽象类。而继承这个抽象类,只需要实现两个方法:create()和wrap(T obj)。
实现create()方法很简单,而实现wrap(T obj)也有捷径,可以使用类DefaultPooledObject,代码可以参考如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
/**
* Created by liyanxin on 2015/3/25.
*/
public class PooledStringBufferFactory extends BasePooledObjectFactory<StringBuffer> {
@Override
public StringBuffer create() throws Exception {
return new StringBuffer( 16 );
}
@Override
public PooledObject<StringBuffer> wrap(StringBuffer stringBuffer) {
return new DefaultPooledObject<StringBuffer>(stringBuffer);
}
}
|
当然还有其他的池对象工厂,如KeyedPooledObjectFactory,和PooledObjectFactory接口类似,只是在相关的方法中多了Key参数,如下,
1
2
3
4
5
6
7
8
9
10
11
12
|
public interface KeyedPooledObjectFactory<K,V> {
PooledObject<V> makeObject(K key) throws Exception;
void destroyObject(K key, PooledObject<V> p) throws Exception;
boolean validateObject(K key, PooledObject<V> p);
void activateObject(K key, PooledObject<V> p) throws Exception;
void passivateObject(K key, PooledObject<V> p) throws Exception;
}
|
创建对象池 GenericObjectPool
在org.apache.commons.pool2.impl中预设了三个可以直接使用的对象池:GenericObjectPool、GenericKeyedObjectPool和SoftReferenceObjectPool。
通常使用GenericObjectPool来创建对象池,如果是对象池是Keyed的,那么可以使用GenericKeyedObjectPool来创建对象池。这两个类都提供了丰富的配置选项。这两个对象池的特点是可以设置对象池中的对象特征,包括LIFO(后进先出)方式、最大空闲数、最小空闲数、是否有效性检查等等。两者的区别如前面所述,后者支持Keyed。
而SoftReferenceObjectPool对象池,它利用一个java.util.ArrayList对象来保存对象池里的对象。不过它并不在对象池里直接保存对象本身,而是保存它们的“软引用”
(Soft Reference)。这种对象池的特色是:可以保存任意多个对象,不会有容量已满的情况发生;在对象池已空的时候,调用它的borrowObject方法,会自动返回新创建的实例;可以在初始化同时,在池内预先创建一定量的对象;当内存不足的时候,池中的对象可以被Java虚拟机回收。
举个例子:
1
|
new GenericObjectPool<StringBuffer>( new PooledStringBufferFactory());
|
我们也可以使用GenericObjectPoolConfig来对上面创建的对象池进行一些参数配置,创建的Config参数,可以使用setConfig方法传给对象池,也可以在对象池的构造方法中作为参数传入。
举个例子:
1
2
3
4
5
|
GenericObjectPoolConfig conf = new GenericObjectPoolConfig();
conf.setMaxTotal( 20 );
conf.setMaxIdle( 10 );
...
GenericObjectPool<StringBuffer> pool = new GenericObjectPool<StringBuffer>( new PooledStringBufferFactory(), conf);
|
使用对象池
对象池使用起来很方便,简单一点就是使用borrowObject和returnObject两个方法,直接给参考代码吧:
borrowObject部分代码,具体请看源码:借出池对象,通过新建create()或从idleObjects双端队列中返回池对象。idleObjects是一个双端队列,保存返回对象池的对象,下次用的时候按照LIFO的原则(或其他原则)借出对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
public T borrowObject( long borrowMaxWaitMillis) throws Exception {
PooledObject<T> p = null ;
while (p == null ) {
create = false ;
if (blockWhenExhausted) {
p = idleObjects.pollFirst();
if (p == null ) {
p = create();
if (p != null ) {
create = true ;
}
}
if (p == null ) {
if (borrowMaxWaitMillis < 0 ) {
p = idleObjects.takeFirst();
} else {
p = idleObjects.pollFirst(borrowMaxWaitMillis,
TimeUnit.MILLISECONDS);
}
}
if (p == null ) {
throw new NoSuchElementException(
"Timeout waiting for idle object" );
}
if (!p.allocate()) {
p = null ;
}
} else {
p = idleObjects.pollFirst();
if (p == null ) {
p = create();
if (p != null ) {
create = true ;
}
}
}
}
return p.getObject();
}
|
returnObject方法,部分代码,具体请看源码:返回池对象,放入idleObjects双端队列保存。
关键代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public void returnObject(T obj) {
PooledObject<T> p = allObjects.get(obj);
int maxIdleSave = getMaxIdle();
if (isClosed() || maxIdleSave > - 1 && maxIdleSave <= idleObjects.size()) {
try {
destroy(p);
} catch (Exception e) {
swallowException(e);
}
} else {
if (getLifo()) {
idleObjects.addFirst(p);
} else {
idleObjects.addLast(p);
}
}
updateStatsReturn(activeTime);
}
|
这只是大体上的逻辑,还有更多的细节逻辑控制。比如什么时候销毁,什么时候创建等等。
==============END==============
转载于:https://www.cnblogs.com/telwanggs/p/5357839.html
commons.pool2 对象池的使用相关推荐
- 面试官问:对象池技术了解吗?apache common pool2呢?
欢迎关注方志朋的博客,回复"666"获面试宝典 对象池顾名思义就是存放对象的池,与我们常听到的线程池.数据库连接池.http连接池等一样,都是典型的池化设计思想. 对象池的优点就是 ...
- common pool2 mysql_连接池Commons Pool2的使用
客户端这边,如果每次都临时建立一个新的连接,那么连接的开销非常大. 业内常用的连接池组件是 Commons Pool2---版本 2.4.2 packageservice.pool; importor ...
- Java中对象池的本质是什么?(实战分析版)
简介 对象池顾名思义就是存放对象的池,与我们常听到的线程池.数据库连接池.http连接池等一样,都是典型的池化设计思想. 对象池的优点就是可以集中管理池中对象,减少频繁创建和销毁长期使用的对象,从而提 ...
- commons-pool2和commons-pool对象池使用
概念 对象池(ObjectPool): 掌管对象的生命周期,获取,激活,验证,钝化,销毁等 池对象(PooledObject): 被创建在池中的对象,自己可以有一些附加信息 池对象工厂(PooledO ...
- commons-pool2自定义对象池-快速开始
文章目录 一.什么是commons-pool2 1. springboot使用commons-pool2实现对象池 二.常用API 1. GenericObjectPool 2. PooledObje ...
- Java 中的对象池实现
点赞再看,动力无限.Hello world : ) 微信搜「 程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. 最近 ...
- 什么是对象池?有什么用?
对象池顾名思义就是存放对象的池,与我们常听到的线程池.数据库连接池.http连接池等一样,都是典型的池化设计思想. 对象池的优点就是可以集中管理池中对象,减少频繁创建和销毁长期使用的对象,从而提升复用 ...
- Unity对象池技术
Unity对象池技术 https://blog.csdn.net/LemonXQ/article/details/77148886 顾名思义,对象池是存放对象的缓冲区.用户可以从缓冲区中放入/取出对象 ...
- commons-pool2(2.6.2)实现对象池-jdk8
commons-pool2(2.6.2)实现对象池-jdk8 springboot web项目中,有很多 非线程安全类(jdk自带或者第三方包引入),每次都创建一个 不太友好.就使用 commons- ...
最新文章
- 戛古 Kakku, Kekku-掸邦 shan state
- python科学计算笔记(十一)pandas中date_range生成指定日期
- google 浏览器默认打开控制台_前端开发调试:浏览器console方法总结
- 织梦黑色互联网建站设计模板
- dbexception.java,mysql – org.h2.jdbc.JdbcSQLException:找不到列“ID”
- 用来测试的mysql建表语句_软件测试基础——MySQL建库、建表SQL语句
- Discuz3.2开启图片列表显示教程
- EasyUI DataGrid 可编辑列级联操作
- 一个back propagation的例子
- Spring父子上下文(WebApplicationContext)(防止事务失效)
- 美团获得小样本学习榜单FewCLUE第一!Prompt Learning+自训练实战
- 免费网站翻译整个文档并保留原格式
- 论文阅读|《面向多目标柔性作业车间调度的强化学习NSGA-Ⅱ算法》
- COB-软封装的一些理解
- 编剧小记 — Contour
- systemUI之statusBar
- app如何添加广告位 uni_uniapp给全端小程序添加激励广告详细教程
- dji大疆机器人冬令营_一文看懂大疆的青少年机器人教育解决方案
- 为什么服务器系统会异常,windows服务器查看系统异常
- c# 中崎_C#版OPOS打印(基于北洋OPOS SDK二次开发包,支持EPSON和北洋、佳博、商祺等支持标准ESC/POS指令的POS打印机)...
热门文章
- (17)FPGA面试技能提升篇(System Verilog)
- oracle导出报错04063,Oracle EXP导出报错的解决方法
- 114实名认证未通过_企业微信怎么实名认证?实名认证后还可以改吗?
- gperf linux 安装_Gperftools安装
- python菜单栏_Python(Tkinter)创建的菜单不会显示
- 【蓝桥杯嵌入式】【STM32】4_TIM之定时器及其中断、PWM初探
- 链路层到网络层的数据传递
- [C++] - C++11 多线程 - Mutex
- 【LeetCode】【HOT】84. 柱状图中最大的矩形(栈)
- linux 挂载和网络命令