一、背景
对于使用面向对象语言开发软件的童鞋们都知道,对象是一个十分重要的概念,用Thinking in Java绪论里面的话说:一切皆是对象。
因为对象的重要性,所以在某些大型的应用系统中,对象会被频繁的创建并使用,这就会导致开发人员需要对系统的性能进行调优,特别是在系统耗时方法更是需要着重优化。幸好,有Apache这样一个组织,给奋斗在第一线的广大IT民工提供了这样一个好使的工具:common-pool。
Commons-pool是一个apache开源组织下的众多项目的一个,其原理很简单:创建一个对象池,将一定数量的对象缓存到这个对象池中,需要使用时直接从对象池中取出对象,使用完后将对象扔回到对象池中即可。下面介绍咱们今天的主角——common-pool。
二、common-pool组件简单说明
common-pool提供的对象池主要有两种:一种是带Key的对象池,这种带Key的对象池是把相同的池对象放在同一个池中,也就是说有多少个key就有多少个池;另一种是不带Key的对象池,这种对象池是把生产完全一致的对象放在同一个池中,但是有时候,单用对池内所有对象一视同仁的对象池,并不能解决的问题,例如:对于一组某些参数设置不同的同类对象——比如一堆指向不同地址的 java.net.URL对象或者一批代表不同语句的java.sql.PreparedStatement对象,用这样的方法池化,就有可能取出不合用的对象。
common-pool给带Key的对象池提供了三类对象:KeyedObjectPool、KeyedPoolableObjectFactory、KeyedObjectPoolFactory;给不带Key的对象池同样提供了三个接口:ObjectPool、PoolableObjectFactory、ObjectPoolFactory。这两组接口中的每个接口的功能都是相同的,即PoolableObjectFactory或KeyedPoolableObjectFactory用于管理被池化对象的产生,激活,挂起,检验和销毁;ObjectPool或KeyedObjectPool用于管理要被池化的对象的接触和归还,并通过PoolableObjectFactory完成相应的操作;ObjectPoolFactory或KeyedObjectPoolFactory作为对应ObjectPool或KeyedObjectPool的工厂,里边有createPool()方法,用于大量生成相同类型和设置的池。
三、common-pool实例
下面通过一个例子具体说明不带Key和带Key这两种对象池的区别:
1.实体类
/** * 实体对象类 */ public class MyBaseObject { private int NumOfGetObjectFormPool ; //记录从池中取出的对象 private boolean activeFlag = false;//对象激活状态,默认不激活 public MyBaseObject(){ activeFlag = true ; System.out.println("Object is activited...."); } public int getNumOfGetObjectFormPool() { return NumOfGetObjectFormPool; } public void setNumOfGetObjectFormPool(int numOfGetObjectFormPool) { NumOfGetObjectFormPool = numOfGetObjectFormPool; } public boolean isActiveFlag() { return activeFlag; } public void setActiveFlag(boolean activeFlag) { this.activeFlag = activeFlag; } }
2.不带Key的工厂类
import org.apache.commons.pool.PoolableObjectFactory; import com.zh.exception.MyException; /** * 管理池里对象的产生,激活,挂起,检验和销毁的工厂类 * 不带Key的池工厂 */ @SuppressWarnings("rawtypes") public class PoolableFactoryWithoutKey implements PoolableObjectFactory{ //激活对象 public void activateObject(Object obj) throws MyException{ ((MyBaseObject)obj).setActiveFlag(true); } //销毁被破坏的对象 public void destroyObject(Object obj) throws MyException{ obj = null ; } //创建对象 public Object makeObject() throws MyException{ return new MyBaseObject(); } //挂起对象 public void passivateObject(Object obj) throws MyException{ ((MyBaseObject)obj).setActiveFlag(false); } //验证该对象是否安全 public boolean validateObject(Object obj){ if(((MyBaseObject)obj).isActiveFlag()){ return true ; } return false; } }
3.带Key的工厂类
import org.apache.commons.pool.KeyedPoolableObjectFactory; import com.zh.exception.MyException; /** * 管理池里对象的产生,激活,挂起,检验和销毁的工厂类 * 带Key的池工厂 */ public class PoolableFactoryWithKey implements KeyedPoolableObjectFactory<String,MyBaseObject>{ //激活对象 public void activateObject(String str,MyBaseObject my_obj) throws MyException{ my_obj.setActiveFlag(true); } //销毁对象 public void destroyObject(String str,MyBaseObject my_obj) throws MyException{ my_obj = null ; } //创建对象 public MyBaseObject makeObject(String str) throws MyException{ MyBaseObject my_obj = new MyBaseObject(); my_obj.setNumOfGetObjectFormPool(0); return my_obj; } //挂起对象 public void passivateObject(String str,MyBaseObject my_obj) throws MyException{ my_obj.setActiveFlag(false); } //验证对象是否安全 public boolean validateObject(String str ,MyBaseObject my_obj){ if(my_obj.isActiveFlag()){ return true ; } return false ; } }
4.测试类
import org.apache.commons.pool.KeyedObjectPool; import org.apache.commons.pool.KeyedPoolableObjectFactory; import org.apache.commons.pool.ObjectPool; import org.apache.commons.pool.PoolableObjectFactory; import org.apache.commons.pool.impl.GenericKeyedObjectPool; import org.apache.commons.pool.impl.GenericObjectPool; import com.zh.exception.MyException; public class CommonPoolTest { public static void main(String[] args) throws Exception{ testCommonPoolWithoutKey(); System.out.println("不带Key的CommonPool执行结束"); System.out.println("----------------------"); testCommonPoolWithKey(); System.out.println("带Key的CommonPool执行结束"); System.out.println("----------------------"); } @SuppressWarnings({ "rawtypes", "unchecked" }) private static void testCommonPoolWithoutKey() throws Exception{ MyBaseObject my_obj = null ; PoolableObjectFactory factoryWithoutKey = new PoolableFactoryWithoutKey(); ObjectPool pool = new GenericObjectPool(factoryWithoutKey); try{ for(int i=0;i<5;i++){ System.out.println("\n>>>>>>" + i + "<<<<<<"); System.out.println("对象池中处于闲置状态的对象:" + pool.getNumIdle()); //将对象池中闲置的对象取出一个 my_obj = (MyBaseObject)pool.borrowObject(); System.out.println("取出的对象:" + my_obj); System.out.println("对象池中所有在用对象的数量:" + pool.getNumActive()); if(i % 2 == 0){//用完之后归还对象 pool.returnObject(my_obj); System.out.println("归还的对象:" + my_obj); } } }catch(MyException e){ System.out.println(e.getErrorMessage()); throw e ; }catch(Exception e){ e.printStackTrace(); }finally{ pool.close(); } } private static void testCommonPoolWithKey() throws Exception{ MyBaseObject my_obj1,my_obj2,my_obj3 = null ; KeyedPoolableObjectFactory<String, MyBaseObject> factoryWithKey = new PoolableFactoryWithKey(); KeyedObjectPool<String, MyBaseObject> pool = new GenericKeyedObjectPool<String,MyBaseObject>(factoryWithKey); try{ //这里添加池对象,只需要传入key就会默认调用makeObject()方法创建一个对象 pool.addObject("A"); pool.addObject("B"); System.out.println("对象池中处于闲置状态的对象:" + pool.getNumIdle()); for(int i=0;i<5;i++){ my_obj1 = pool.borrowObject("A");//从对象池中取Key=A的对象 my_obj1.setNumOfGetObjectFormPool(my_obj1.getNumOfGetObjectFormPool() + 1); System.out.println("A" + i + ">>>>" + my_obj1 + "<<<<" + my_obj1.getNumOfGetObjectFormPool()); my_obj2 = pool.borrowObject("B"); //从对象池中取Key=B的对象 my_obj2.setNumOfGetObjectFormPool(my_obj2.getNumOfGetObjectFormPool() + 1); System.out.println("B" + i + ">>>>" + my_obj2 + "<<<<" + my_obj2.getNumOfGetObjectFormPool()); //如果对象池中有Key=C的闲置对象,则也会默认创建一个Key=C的池对象 my_obj3 = pool.borrowObject("C"); my_obj3.setNumOfGetObjectFormPool(my_obj3.getNumOfGetObjectFormPool() + 1); System.out.println("C" + i + ">>>>" + my_obj3 + "<<<<" + my_obj3.getNumOfGetObjectFormPool()); if(i < 3){//用完归还对象 pool.returnObject("A", my_obj1); pool.returnObject("B", my_obj2); pool.returnObject("C", my_obj3); System.out.println("归还的对象:" + my_obj1 + "," + "my_obj2" + "," + "my_obj3"); } } System.out.println("当前对象池中的所有对象:" + pool.getNumActive()); System.out.println("当前对象池中处于闲置状态的对象:" + pool.getNumIdle()); }catch(MyException e){ System.out.println(e.getErrorMessage()); throw e ; }catch(Exception e){ e.printStackTrace(); }finally{ pool.close(); } } }
5.测试结果
>>>>>>0<<<<<<
对象池中处于闲置状态的对象:0
Object is activited....
取出的对象:com.zh.learn.common.pool.MyBaseObject@73a2335d
对象池中所有在用对象的数量:1
归还的对象:com.zh.learn.common.pool.MyBaseObject@73a2335d
>>>>>>1<<<<<<
对象池中处于闲置状态的对象:1
取出的对象:com.zh.learn.common.pool.MyBaseObject@73a2335d
对象池中所有在用对象的数量:1
>>>>>>2<<<<<<
对象池中处于闲置状态的对象:0
Object is activited....
取出的对象:com.zh.learn.common.pool.MyBaseObject@717da562
对象池中所有在用对象的数量:2
归还的对象:com.zh.learn.common.pool.MyBaseObject@717da562
>>>>>>3<<<<<<
对象池中处于闲置状态的对象:1
取出的对象:com.zh.learn.common.pool.MyBaseObject@717da562
对象池中所有在用对象的数量:2
>>>>>>4<<<<<<
对象池中处于闲置状态的对象:0
Object is activited....
取出的对象:com.zh.learn.common.pool.MyBaseObject@6ff4ff23
对象池中所有在用对象的数量:3
归还的对象:com.zh.learn.common.pool.MyBaseObject@6ff4ff23
不带Key的CommonPool执行结束
----------------------
Object is activited....
Object is activited....
对象池中处于闲置状态的对象:2
A0>>>>com.zh.learn.common.pool.MyBaseObject@2b49959a<<<<1
B0>>>>com.zh.learn.common.pool.MyBaseObject@6bfcc7a9<<<<1
Object is activited....
C0>>>>com.zh.learn.common.pool.MyBaseObject@20985fa2<<<<1
归还的对象:com.zh.learn.common.pool.MyBaseObject@2b49959a,my_obj2,my_obj3
A1>>>>com.zh.learn.common.pool.MyBaseObject@2b49959a<<<<2
B1>>>>com.zh.learn.common.pool.MyBaseObject@6bfcc7a9<<<<2
C1>>>>com.zh.learn.common.pool.MyBaseObject@20985fa2<<<<2
归还的对象:com.zh.learn.common.pool.MyBaseObject@2b49959a,my_obj2,my_obj3
A2>>>>com.zh.learn.common.pool.MyBaseObject@2b49959a<<<<3
B2>>>>com.zh.learn.common.pool.MyBaseObject@6bfcc7a9<<<<3
C2>>>>com.zh.learn.common.pool.MyBaseObject@20985fa2<<<<3
归还的对象:com.zh.learn.common.pool.MyBaseObject@2b49959a,my_obj2,my_obj3
A3>>>>com.zh.learn.common.pool.MyBaseObject@2b49959a<<<<4
B3>>>>com.zh.learn.common.pool.MyBaseObject@6bfcc7a9<<<<4
C3>>>>com.zh.learn.common.pool.MyBaseObject@20985fa2<<<<4
Object is activited....
A4>>>>com.zh.learn.common.pool.MyBaseObject@73ae9565<<<<1
Object is activited....
B4>>>>com.zh.learn.common.pool.MyBaseObject@4ad25538<<<<1
Object is activited....
C4>>>>com.zh.learn.common.pool.MyBaseObject@36d8f5e8<<<<1
当前对象池中的所有对象:6
当前对象池中处于闲置状态的对象:0
带Key的CommonPool执行结束
----------------------
相关推荐
Common-Pool2.jar是Apache Commons Pool库的第二个主要版本,这是一个对象池设计模式的实现,用于提高对象的重用性,减少创建和销毁对象的开销。在Jedis中,它被用于管理Redis连接,通过复用已建立的连接,避免频繁...
赠送jar包:commons-pool2-2.0.jar; 赠送原API文档:commons-pool2-2.0-javadoc.jar; 赠送源代码:commons-pool2-2.0-sources.jar; 赠送Maven依赖信息文件:commons-pool2-2.0.pom; 包含翻译后的API文档:...
赠送jar包:commons-pool2-2.10.0.jar; 赠送原API文档:commons-pool2-2.10.0-javadoc.jar; 赠送源代码:commons-pool2-2.10.0-sources.jar; 赠送Maven依赖信息文件:commons-pool2-2.10.0.pom; 包含翻译后的API...
需要使用Redis连接池的话,还需commons-pool包,提供了强大的功能,包含最新的jar包
`common-pool2`是Apache Commons Pool的第二个主要版本,它提供了对对象池的实现,允许开发者高效地管理和重用对象,避免频繁创建和销毁对象带来的开销。这个库不仅适用于Jedis,还可以应用于任何需要池化对象的场景...
Apache Commons Pool2是Java开发中的一个对象池库,主要用于提高对象的重用效率,从而提升系统性能。在本文中,我们将深入探讨这个库的核心概念、设计模式以及如何通过源码学习来理解其工作原理。 首先,Apache ...
DBCP(DataBase Connection Pool)是 apache common上的一个 java 连接池项目,也是 tomcat 使用的连接池组件,依赖 于Jakarta commons-pool 对象池机制,DBCP可以直接的在应用程序中使用。 使用DBCP会用到commons-...
对应Maven信息:groupId:org.apache.commons,artifactId:commons-pool2,version:2.5.0 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构...
标签:apache、pool2、commons、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准...
DBCP(Database Connection Pool)是Apache Jakarta项目中的一个子项目,它利用了commons-pool对象池机制来实现数据库连接的复用,从而减少创建和释放数据库连接时的开销。Tomcat,一个广泛使用的Java应用服务器,...
《Apache Commons Pool 2.8.1:高效对象池实现详解》 Apache Commons Pool 是一个广泛使用的开源组件,主要用于提供对象池化的实现。在Java世界里,对象池化是一种优化资源管理的重要技术,通过复用已创建的对象,...
**Apache Commons Pool** 是Apache Commons项目下的一个子项目,主要目标是为Java开发者提供一种简单高效的方式来管理对象池。该库允许开发者创建一个可重用的对象池,从而避免了重复创建和销毁对象带来的开销,特别...
赠送jar包:commons-pool2-2.10.0.jar; 赠送原API文档:commons-pool2-2.10.0-javadoc.jar; 赠送源代码:commons-pool2-2.10.0-sources.jar; 赠送Maven依赖信息文件:commons-pool2-2.10.0.pom; 包含翻译后的API...
go-commons-pool, 用于golang的通用对象池 共享池 go公共池是用于 Golang的通用对象池,直接从 Apache公共池重写。特性支持自定义 PooledObjectFactory 。Rich pool配置选项,可以精确控制池对象生命周期。 请参见 ...
commons-dbcp-1.4 jar java连接池. .commons-dbcp 是 apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件。单独使用dbcp需要3个包:
Apache Commons Pool 是一个Java对象池库,主要用于提供各种对象池化的实现,以便高效地管理和复用有限的资源。标题中的"commo-pool, commons-pool commons-pool commons-pool"可能是由于输入错误,正确的应该是...
标签:apache、pool2、commons、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准...
标题中的“Jedis-Common-Pool”指的是Jedis,一个流行的Java客户端库,用于与Redis内存数据存储系统交互,以及Apache Commons Pool 2,这是一个对象池实现,Jedis使用它来管理Redis连接的生命周期,提高性能和资源...
使用JDK1.8、SpringBoot2.2.10.RELEASE、lombok1.18.8、guava23.0、hutool5.3.10、commons-pool2 2.7.0、tika1.22等实现多Ftp连接池实现,通过守护线程实现连接池内连接可用性校验,配置最大、最小连接个数防止Ftp...
Jedis是专为处理Redis数据存储服务而设计的一个Java客户端,而Apache Commons Pool则是一个通用的对象池服务,它可以用于创建和管理对象池,包括Jedis实例。 **Jedis** Jedis是Redis官方推荐的Java客户端之一,它...