commons-pool实战之 GenericObjectPool和GenericKeyedObjectPool
前面两篇文章说了怎么样简单的使用commons-pool库,这里需要考虑一个问题就是在很多时候我们在池里的对象都是比较重型的并且大多数比较稀缺的 资源,比如说数据库连接,这样如果一直把一些连接放在池里不归还,就会很占资源,并且是这些资源利用率降低,那么怎样才能更好的管理池子中的资源 呢,commons-pool里提供了一个GenericObjectPool类,它的出现使上面的问题就迎刃而解了。同样对于 GenericObjectPool类,也就有一个对应的GenericKeyedObjectPool类。
下面还是例子说话
一个Connection类,可以想象成一个远程连接比如数据库连接等。其中包括创建连接,关闭连接,和一个print方法。
- package com.googlecode.garbagecan.commons.pool.sample3;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- public class MyConnection {
- private static Logger logger = LoggerFactory.getLogger(MyConnection.class);
- private String name;
- private boolean connected;
- public MyConnection(String name) {
- this.name = name;
- }
- public void connect() {
- this.connected = true;
- logger.info(name + ": " + connected);
- }
- public void close() {
- this.connected = false;
- logger.info(name + ": " + connected);
- }
- public boolean isConnected() {
- return this.connected;
- }
- public String getName() {
- return this.name;
- }
- public void print() {
- logger.info(this.name);
- }
- }
一个PoolableObjectFactory接口的实现类,提供makeObject, activateObject, passivateObject, validateObject, destroyObject方法。
- package com.googlecode.garbagecan.commons.pool.sample3;
- import org.apache.commons.pool.PoolableObjectFactory;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- public class MyConnectionPoolableObjectFactory implements PoolableObjectFactory {
- private static Logger logger = LoggerFactory.getLogger(MyConnectionPoolableObjectFactory.class);
- private static int count = 0;
- public Object makeObject() throws Exception {
- MyConnection myConn = new MyConnection(generateName());
- logger.info(myConn.getName());
- myConn.connect();
- return myConn;
- }
- public void activateObject(Object obj) throws Exception {
- MyConnection myConn = (MyConnection)obj;
- logger.info(myConn.getName());
- }
- public void passivateObject(Object obj) throws Exception {
- MyConnection myConn = (MyConnection)obj;
- logger.info(myConn.getName());
- }
- public boolean validateObject(Object obj) {
- MyConnection myConn = (MyConnection)obj;
- logger.info(myConn.getName());
- return myConn.isConnected();
- }
- public void destroyObject(Object obj) throws Exception {
- MyConnection myConn = (MyConnection)obj;
- logger.info(myConn.getName());
- myConn.close();
- }
- private synchronized String generateName() {
- return "conn_" + (++count);
- }
- }
一个测试类
- package com.googlecode.garbagecan.commons.pool.sample3;
- import org.apache.commons.pool.ObjectPool;
- import org.apache.commons.pool.PoolableObjectFactory;
- import org.apache.commons.pool.impl.GenericObjectPool;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- public class Test {
- private static Logger logger = LoggerFactory.getLogger(Test.class);
- public static void main(String[] args) {
- //test1();
- //test2();
- //test3();
- }
- private static void test1() {
- PoolableObjectFactory factory = new MyConnectionPoolableObjectFactory();
- GenericObjectPool.Config config = new GenericObjectPool.Config();
- config.lifo = false;
- config.maxActive = 5;
- config.maxIdle = 5;
- config.minIdle = 1;
- config.maxWait = 5 * 1000;
- ObjectPool pool = new GenericObjectPool(factory, config);
- for (int i = 0; i < 10; i++) {
- Thread thread = new Thread(new MyTask(pool));
- thread.start();
- }
- //closePool(pool);
- }
- private static void test2() {
- PoolableObjectFactory factory = new MyConnectionPoolableObjectFactory();
- GenericObjectPool.Config config = new GenericObjectPool.Config();
- config.lifo = false;
- config.maxActive = 5;
- config.maxIdle = 5;
- config.minIdle = 1;
- config.maxWait = 20 * 1000;
- ObjectPool pool = new GenericObjectPool(factory, config);
- for (int i = 0; i < 10; i++) {
- Thread thread = new Thread(new MyTask(pool));
- thread.start();
- }
- //closePool(pool);
- }
- private static void test3() {
- PoolableObjectFactory factory = new MyConnectionPoolableObjectFactory();
- GenericObjectPool.Config config = new GenericObjectPool.Config();
- config.lifo = false;
- config.maxActive = 5;
- config.maxIdle = 0;
- config.minIdle = 0;
- config.maxWait = -1;
- ObjectPool pool = new GenericObjectPool(factory, config);
- Thread thread = new Thread(new MyTask(pool));
- thread.start();
- try {
- Thread.sleep(60L * 1000L);
- } catch (Exception e) {
- e.printStackTrace();
- }
- //closePool(pool);
- }
- private static void closePool(ObjectPool pool) {
- try {
- pool.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- private static class MyTask implements Runnable {
- private ObjectPool pool;
- public MyTask(ObjectPool pool) {
- this.pool = pool;
- }
- public void run() {
- MyConnection myConn = null;
- try {
- myConn = (MyConnection)pool.borrowObject();
- try {
- myConn.print();
- } catch(Exception ex) {
- pool.invalidateObject(myConn);
- myConn = null;
- }
- Thread.sleep(10L * 1000L);
- } catch(Exception ex) {
- logger.error("Cannot borrow connection from pool.", ex);
- } finally {
- if (myConn != null) {
- try {
- pool.returnObject(myConn);
- } catch (Exception ex) {
- logger.error("Cannot return connection from pool.", ex);
- }
- }
- }
- }
- }
- }
其中包含了三个方法,分别测试了三种情况;
- 类中包含了一个实现了Runnable接口的内部类,目的是为了启动几个线程来模拟的对连接类的使用,并且为了尽可能的真实,在run方法里sleep了10秒中;
- 首
先运行测试方法test1()可以看到,在循环10个线程申请Connection类时,前面5个可以很好的获取,但是后面5个线程就不能获取连接,并且
抛出了异常,这是由于“config.maxActive = 5;”和“config.maxWait = 5 *
1000;”在起作用,由于配置了最大活动连接是5个,并且后续申请没有有效连接的等待时间是5秒,所以test1方法中后面五个线程在等了5秒后全部抛
出异常,表明不能申请连接了。 - 下面运行test2()方法,在test2中把“config.maxWait = 20 * 1000;”改成了20秒,而我们程序中每个线程使用连接会用去10秒,所以后面五个线程在等待了10秒后就全部获取连接了,所以程序最后会运行成功。
- 再
看test3()方法,其中把maxIdle和minIdle都改为0,就是在连接不用时立即真正归还连接,对于数据库连接来说就是关闭物理连接,而
maxWait改为-1,就是如果没有申请到连接就永远等待,运行test3()方法,观察日志,可以看出程序在用户连接对象以后,会调用
MyConnectionPoolableObjectFactory.destroyObject()和MyConnection.close()方法
来销毁对象。所以如果是使用这样的配置,就相当于每次都是物理连接,用完后就关闭连接。当然这里是一个极端的例子,真实情况下不会把maxIdle和
minIdle都设为0的。
其实对于GenericObjectPool.Config类和GenericKeyedObjectPool.Config类还是有很多配置参数的,这里只是列出的最简单的几个常用的,具体可以参考官方文档。
来源:http://blog.csdn.net/kongxx/article/details/6612760
源码地址:https://github.com/apache/commons-pool
commons-pool实战之 GenericObjectPool和GenericKeyedObjectPool的更多相关文章
- NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool
错误:Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/pool/impl ...
- Spring + Tomcat 启动报错java.lang.ClassNotFoundException: org.apache.commons.pool.impl.GenericObjectPool
错误如下: -- ::,-[TS] INFO http-- org.springframework.beans.factory.support.DefaultListableBeanFactory - ...
- org/apache/commons/pool/impl/GenericObjectPool异常的解决办法
org/apache/commons/pool/impl/GenericObjectPool异常的解决办法 webwork+spring+hibernate框架的集成, 一启动Tomcat服务器就出了 ...
- 对象池化技术 org.apache.commons.pool
恰当地使用对象池化技术,可以有效地减少对象生成和初始化时的消耗,提高系统的运行效率.Jakarta Commons Pool组件提供了一整套用于实现对象池化的框架,以及若干种各具特色的对象池实现,可以 ...
- apache commons pool
apache commons下的pool 其中的borrowObject函数源代码显示其产生可用对象的过程: 如果stack中有空闲的对象,则pop对象,激活对象(activate函数),验证对象(v ...
- Apache Commons Pool 故事一则
Apache Commons Pool 故事一则 最近工作中遇到一个由于对commons-pool的使用不当而引发的问题,习得正确的使用姿势后,写下这个简单的故事,帮助理解Apache Commons ...
- 池化 - Apache Commons Pool
对于那些创建耗时较长,或者资源占用较多的对象,比如网络连接,线程之类的资源,通常使用池化来管理这些对象,从而达到提高性能的目的.比如数据库连接池(c3p0, dbcp), java的线程池 Execu ...
- JedisCluster中应用的Apache Commons Pool对象池技术
对象池技术在服务器开发上应用广泛.在各种对象池的实现中,尤其以数据库的连接池最为明显,可以说是每个服务器必须实现的部分. apache common pool 官方文档可以参考:https://c ...
- Cache Lucene IndexReader with Apache Commons Pool
IndexReaderFactory.java 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 2 ...
随机推荐
- HTML 事件处理
1.HTML事件处理程序 2.DOM0级事件处理程序 3.DOM2级事件处理程序 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transi ...
- Shell变量的定义与赋值操作注意事项
1 shell变量是弱类型 * 声明变量不用声明类型 * 可以存储不同类型的内容 * 使用时要明确变量的类型 * 区分大小写 2 变量声明及赋值格式 2.1 格式 变量名=变量值 # 注意等号两侧不 ...
- SPOJ GSS4 Can you answer these queries IV
Time Limit: 500MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Description You are g ...
- BeautifulSoup高级应用 之 CSS selectors /CSS 选择器
BeautifulSoup支持最常用的CSS selectors,这是将字符串转化为Tag对象或者BeautifulSoup自身的.select()方法. 本篇所使用的html为: html_doc ...
- django views中提示cannot convert dictionary update sequence element #0 to a sequence错误
def message(request): message_list = MessageBoard.objects.all().order_by('-pk') return render(reques ...
- Java线程池的那些事
熟悉java多线程的朋友一定十分了解java的线程池,jdk中的核心实现类为java.util.concurrent.ThreadPoolExecutor.大家可能了解到它的原理,甚至看过它的源码:但 ...
- linux(centos) 项目部署阶段相关命令汇总
1.ssh免密码登陆主要命令cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys-->添加公钥service sshd restart -- ...
- 使用Keil uVision下载hex文件
在uVision3/uVision4/uVision5中,可以创建一个项目用来下载HEX文件到flash里面. 具体步骤如下: 1. 在菜单中,选择 Project - New Project... ...
- Extjs GridPanel用法详解
Extjs GridPanel 提供了非常强大数据表格功能,在GridPanel可以展示数据列表,可以对数据列表进行选择.编辑等.在之前的Extjs MVC开发模式详解中,我们已经使用到了GridPa ...
- CSS3自适配手机屏幕
@media only screen and (max-width:350px){ .img{ width: 80px; height:70px; background-image: url(./im ...