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 ...
随机推荐
- xml解析工具-jdom
前言:近期接触SSH框架的时候,经常得配置一下xml文件:今天闲来没事就挖挖xml解析的原理供大伙儿分享.本文主要通过一个简单的例子解析一个xml文件.明白其中缘由之后,大家想定义自己的xml也绝非难 ...
- 【BZOJ-1976】能量魔方Cube 最小割 + 黑白染色
1976: [BeiJing2010组队]能量魔方 Cube Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 884 Solved: 307[Submi ...
- spring的自动装配基础
当开始看别人的代码使用注解的时候,以为照着别人的代码写,也写一个注释就能实现这样的功能,但是,现在开始考虑自动装配时怎样实现的. 首先,如果如果知道如何手动在xml配置中"装配bean&qu ...
- css中margin-top/margin-bottom失效
要设置这两个值,我的理解应该在这个div的父容器中设置了固定宽高,或者设置了绝对定位,比如position:absolute(绝对定位) 或者压根不用,直接用padding-top/padding-b ...
- Jenkins的FTP上传插件Publish Over FTP Plugin设置支持中文路径
[系统管理]->[系统设置]->[Publish over FTP]->[Control encoding]->输入[GB2312]或者[UTF-8]
- 环信webim1.1.2版本在windows下npm环境搭建错误解决
1.1.2版本的webim从ui到整体的代码结构都做了很大改变,从代码结构上采用node.js的环境进行开发和打包,最终打包的输出项目,不依赖node.js的环境进行运行,得益于webpack的打包实 ...
- TYVJ1427 小白逛公园
时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 小新经常陪小白去公园玩,也就是所谓的遛狗啦…在小新家附近有一条“公园路”,路的一边从南到北依次排着n个 ...
- Linux inode && Fast Directory Travel Method(undone)
目录 . Linux inode简介 . Fast Directory Travel Method 1. Linux inode简介 0x1: 磁盘分割原理 字节 -> 扇区(sector)(每 ...
- IAR使用记录
1. Project-->Options... 更改器件:General-->Target-->Device 添加其它需包含的目录:C/C++ Compiler-->Prepr ...
- matlab从txt文本导入数据作图
Matlab上 fr = fopen('d:\Matlab\长期纪录2014-3-11.txt', 'r');data=fscanf(fr,'%f',[1,inf]);axis([0 90000 -8 ...