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==============
commons.pool2 对象池的使用的更多相关文章
- JedisCluster中应用的Apache Commons Pool对象池技术
对象池技术在服务器开发上应用广泛.在各种对象池的实现中,尤其以数据库的连接池最为明显,可以说是每个服务器必须实现的部分. apache common pool 官方文档可以参考:https://c ...
- Apache common pool2 对象池
对象池的容器:包含一个指定数量的对象.从池中取出一个对象时,它就不存在池中,直到它被放回.在池中的对象有生命周期:创建,验证,销毁,对象池有助于更好地管理可用资源,防止JVM内部大量临时小对象,频繁触 ...
- 缓冲&缓存&对象池概念的理解
一).缓冲 作用:缓解程序上下层之间的性能差异. 1).当上层组件的性能优于下层组件时加入缓冲机制可以减少上层组件对下 层组件的等待时间. 2).上层组件不需要等待下层组件接收全部数据,即可返回操作, ...
- Java--对象池化技术 org.apache.commons.pool2.ObjectPool
org.apache.commons.pool2.ObjectPool提供了对象池,开发的小伙伴们可以直接使用来构建一个对象池 使用该对象池具有两个简单的步骤: 1.创建对象工厂,org.apache ...
- 对象池化技术 org.apache.commons.pool
恰当地使用对象池化技术,可以有效地减少对象生成和初始化时的消耗,提高系统的运行效率.Jakarta Commons Pool组件提供了一整套用于实现对象池化的框架,以及若干种各具特色的对象池实现,可以 ...
- Lettuce连接池——解决“MXBean already registered with name org.apache.commons.pool2:type=GenericObjectPool,name=pool”
LettuceConfig: package com.youdao.outfox.interflow.config; import io.lettuce.core.support.Connection ...
- Apache Common-pool2对象池分析和应用
Apache Common-pool2包提供了一个通用的对象池技术的实现.可以很方便的基于它来实现自己的对象池,比如DBCP和Jedis他们的内部对象池的实现就是依赖于Common-pool2. 对象 ...
- Apache Commons Pool2 源码分析 | Apache Commons Pool2 Source Code Analysis
Apache Commons Pool实现了对象池的功能.定义了对象的生成.销毁.激活.钝化等操作及其状态转换,并提供几个默认的对象池实现.在讲述其实现原理前,先提一下其中有几个重要的对象: Pool ...
- java对象池commons-pool-1.6详解(一)
自己的项目中用到了 对象池 commons-pool: package com.sankuai.qcs.regulation.protocol.client; import com.dianping. ...
随机推荐
- Ubuntu apache
Linux系统为Ubuntu 1. 启动apache服务 # /etc/init.d/apache2 start 2. 重启apache服务 # /etc/init.d/apache2 restart ...
- python 正则表达式应用——缩写词扩充
看具体示例 import re def expand_abbr(sen, abbr): lenabbr = len(abbr) ma = '' for i in range(0, lenabbr): ...
- linux免密登录ssh验证配置方法及常见错误解决
目标:从服务器A免密登录服务器B [配置方法] 1.在服务器A生成密钥文件,直接使用以下命令: ssh-keygen 中间遇到输入内容一路回车即可,完成后会在 ~/.ssh 目录下生成两个文件:id_ ...
- JMS - ActiveMQ的简单使用
首先需要下载ActiveMQ,下面的链接给我们列出了所有版本:http://activemq.apache.org/download-archives.html每个版本为不同的OS提供了链接: 公司电 ...
- asp.net Core2.1连接到Mysql 数据库
1.首先,安装相关插件 在nuget下安装 1.Pomelo.EntityFrameworkCore.MySql 2.MySql.Data.EntityFrameworkCore 都要是2.1 < ...
- java导入excle表格,并且对表格进行相应的修改,并对表格数据进行整理,最后导出本地表格等一系列操作
1.首先创建一个java项目 完成效果如下图所示 2.导入以下jar包 3.代码如下 其中行和列的操作是根据需求自动划分的 public class auto_date { private stati ...
- java实现Redis分布式锁
网上到处都是分布式锁的代码,基本都是通过setNX 和 expire 这两个不是原子操作,肯定会有问题,不乏好多人通过用setNX的value当做过期时间来弥补等等.但是好像都不太好,或者多少有点问题 ...
- Java温故而知新(10)类的加载机制
类加载是Java程序运行的第一步,研究类的加载有助于了解JVM执行过程,并指导开发者采取更有效的措施配合程序执行. 研究类加载机制的第二个目的是让程序能动态的控制类加载,比如热部署等,提高程序的灵活性 ...
- java-IO小记
说来惭愧,工作一年多了,对io仍然不是很了解.不仅是io,还有网络,还有多线程.shame!!! 接下来的日子里,先搞多线程,再搞io,再搞网络,半年内一定要完成! 好了,今天终于搞懂了outputS ...
- JS小案例(基础好烦恼少)----持续更新
*************************************************** <!DOCTYPE html> <html lang="en&quo ...