`

Apache对象池插件common-pool学习小结

    博客分类:
  • Java
阅读更多

一、背景

       对于使用面向对象语言开发软件的童鞋们都知道,对象是一个十分重要的概念,用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执行结束

----------------------

分享到:
评论

相关推荐

    commons-pool2-2.0-API文档-中文版.zip

    赠送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文档:...

    commons-pool2-2.10.0-API文档-中文版.zip

    赠送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...

    commons-pool2-2.11.1-bin.zip

    DBCP(DataBase Connection Pool)是 apache common上的一个 java 连接池项目,也是 tomcat 使用的连接池组件,依赖 于Jakarta commons-pool 对象池机制,DBCP可以直接的在应用程序中使用。 使用DBCP会用到commons-...

    commons-pool2-2.5.0-API文档-中英对照版.zip

    对应Maven信息:groupId:org.apache.commons,artifactId:commons-pool2,version:2.5.0 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构...

    commons-pool2-2.3-API文档-中文版.zip

    标签:apache、pool2、commons、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准...

    commons-pool2-2.4.3-API文档-中文版.zip

    赠送jar包:commons-pool2-2.4.3.jar; 赠送原API文档:commons-pool2-2.4.3-javadoc.jar; 赠送源代码:commons-pool2-2.4.3-sources.jar; 赠送Maven依赖信息文件:commons-pool2-2.4.3.pom; 包含翻译后的API文档...

    commons-pool2-2.10.0-API文档-中英对照版.zip

    赠送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的通用对象池.zip

    go-commons-pool, 用于golang的通用对象池 共享池 go公共池是用于 Golang的通用对象池,直接从 Apache公共池重写。特性支持自定义 PooledObjectFactory 。Rich pool配置选项,可以精确控制池对象生命周期。 请参见 ...

    common-dbcp.jar,common-pool.jar,common-collections.jar

    commons-dbcp-1.4 jar java连接池. .commons-dbcp 是 apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件。单独使用dbcp需要3个包:

    SpringBoot2.2+commons-pool2实现多Ftp连接池完整项目,开箱即用,经过长期生产使用稳定可靠

    使用JDK1.8、SpringBoot2.2.10.RELEASE、lombok1.18.8、guava23.0、hutool5.3.10、commons-pool2 2.7.0、tika1.22等实现多Ftp连接池实现,通过守护线程实现连接池内连接可用性校验,配置最大、最小连接个数防止Ftp...

    Apache commons-pool2-2.4.2源码学习笔记

    NULL 博文链接:https://aperise.iteye.com/blog/2399752

    commons-pool 等jar包

    DBCP (Database Connection Pool)是一个依赖 Jakarta commons-pool 对象池机制的数据库连接池,Tomcat 的数据源使用的就是 DBCP。

    commons-pool-1.5.6-bin.zip

    Apache commons-pool本质上是"对象池",即通过一定的规则来维护对象集合的容器;commos-pool在很多场景中,用来实现"连接池"/"任务worker池"等,大家常用的dbcp数据库连接池,也是基于commons-pool实现.

    hadoop插件apache-hadoop-3.1.0-winutils-master.zip

    windows下hadoop安装,hadoop插件apache-hadoop-3.1.0-winutils-master.zip

    commons-pool2-2.9.0-API文档-中文版.zip

    赠送jar包:commons-pool2-2.9.0.jar; 赠送原API文档:commons-pool2-2.9.0-javadoc.jar; 赠送源代码:commons-pool2-2.9.0-sources.jar; 赠送Maven依赖信息文件:commons-pool2-2.9.0.pom; 包含翻译后的API文档...

    apache-solr-common-1.3.0.jar

    jar包,亲测可用

    Apache commons-pool2-2.5.0

    The Apache Commons Pool open source software library provides an object-pooling API and a number of object pool implementations. Version 2 of Apache Commons Pool contains a completely re-written ...

    commons-pool2-2.5.0-API文档-中文版.zip

    标签:apache、pool2、commons、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准...

    Apache的对象池化工具commons-pool

    当我们的应用中创建一个十分最重量级的对象的时候,往往为了节省资源成本,使用单例模式,整个的应用中就只有一个对象供大家使用。这样是节省了不少资源,也是大多数应用的做法。不过如果遇到并发量十分大的情况下,...

    com.springsource.org.apache.commons.pool-sources-1.5.3.jar

    com.springsource.org.apache.commons.pool-sources-1.5.3.jar源码

Global site tag (gtag.js) - Google Analytics