利用Apache commons pool2构建池应用

来源:互联网 发布:php 个性化推荐系统 编辑:程序博客网 时间:2024/04/29 21:26

commons pool2与commons pool1还是有很大的差别的,本文主要记录利用commons pool2构建自己的池应用。

1 依赖的引入

        <dependency>            <groupId>org.apache.commons</groupId>            <artifactId>commons-pool2</artifactId>            <version>2.4.2</version>            <type>jar</type>            <scope>compile</scope>        </dependency>

2 构建自己的池应用

ps:本文构建一个string池,从池获取string对象
2.1 构建自己的PooledObjectFactory

PooledObjectFactory是一个池化对象工厂接口,定义了生成对象、激活对象、钝化对象、销毁对象的方法,其方法如下:

public interface PooledObjectFactory<T> {  /**  * 生成对象  */  PooledObject<T> makeObject() throws Exception; /**  * 销毁对象  */  void destroyObject(PooledObject<T> p) throws Exception; /**  * 验证对象  */  boolean validateObject(PooledObject<T> p); /**  * 激活对象  */  void activateObject(PooledObject<T> p) throws Exception; /**  * 钝化对象  */  void passivateObject(PooledObject<T> p) throws Exception;}

如果需要使用Commons-Pool构建构建自己的池应用,那么就需要提供一个PooledObjectFactory接口的具体实现。当然也可以继承BasePooledObjectFactory这个抽象类。本文实现PooledObjectFactory接口,如下所示:

public class StringFactory implements PooledObjectFactory<String>{    public StringFactory(){        System.out.println("init string factory..");    }    public void activateObject(PooledObject<String> pool) throws Exception {        // TODO Auto-generated method stub    }    public void destroyObject(PooledObject<String> pool) throws Exception {        String str = pool.getObject();        if(str!=null){            str=null;            System.out.println(str+" destroy...");        }    }    public PooledObject<String> makeObject() throws Exception {        String i = UUID.randomUUID().toString();        System.out.println("make "+i+" success...");        return new DefaultPooledObject<String>(i);    }    public void passivateObject(PooledObject<String> pool) throws Exception {        // TODO Auto-generated method stub    }    public boolean validateObject(PooledObject<String> pool) {        // TODO Auto-generated method stub        return false;    }}

2.2 创建对象池

在org.apache.commons.pool2.impl中有三个可以直接使用的对象池:GenericObjectPool、GenericKeyedObjectPool和SoftReferenceObjectPool。

通常使用GenericObjectPool来创建对象池,如果是对象池是Keyed的,那么可以使用GenericKeyedObjectPool来创建对象池。

而SoftReferenceObjectPool对象池,它利用一个java.util.ArrayList对象来保存对象池里的对象。不过它并不在对象池里直接保存对象本身,而是保存它们的“软引用”。
(1)GenericObjectPool的使用
如下所示为GenericObjectPool的使用:

        GenericObjectPoolConfig conf = new GenericObjectPoolConfig();        conf.setMaxTotal(10);        GenericObjectPool<String> pool = new GenericObjectPool<String>(new StringFactory(), conf);        for(int i=0;i<15;i++){            System.out.println(i+":");            try {                String str = pool.borrowObject();                System.out.println(str);            } catch (Exception e) {                e.printStackTrace();            }                  }

上例中设置GenericObjectPool的maxTotal为10,开启一个循环(循环次数为15),每次从池中拿一个对象,由于池的大小为10,每次拿到对象之后没有释放,所以程序block在i=10处。
这里写图片描述
下面的例子为每次拿到对象之后,处理完再释放:

GenericObjectPoolConfig conf = new GenericObjectPoolConfig();        conf.setMaxTotal(10);        GenericObjectPool<String> pool = new GenericObjectPool<String>(new StringFactory(), conf);        for(int i=0;i<15;i++){            System.out.println(i+":");            try {                String str = pool.borrowObject();                System.out.println(str);                pool.returnObject(str);            } catch (Exception e) {                e.printStackTrace();            }                  }

其运行结果如下:
这里写图片描述

(2)自定义pool
如下所示为自定义Pool实现了Closeable接口,定义自己的获取资源与释放资源的方法。

public class Pool implements Closeable{  public GenericObjectPool<String> innerPool;  public Pool() {  }  public Pool(final GenericObjectPoolConfig poolConfig,PooledObjectFactory<String> factory){     initPool(poolConfig, factory);   }  public void close() throws IOException {    innerPool.close();  }  public void initPool(final GenericObjectPoolConfig poolConfig,PooledObjectFactory<String> factory){     if(this.innerPool!=null){         System.out.println("innerPool is not null,destroy it..");         innerPool.close();     }      this.innerPool = new GenericObjectPool<String>(factory,poolConfig);  }  public String getResource(){    String str = "";    try {        str=this.innerPool.borrowObject();        System.out.println("get resource success..:"+str);    } catch (Exception e) {         e.printStackTrace();        System.out.println("get resource error...");    }finally{        return str;    }     }  public void returnResourceObject(final String resource){      if(resource==null){          return;      }      innerPool.returnObject(resource);      System.out.println("return resource success.."+resource);  }}

其StringPool继承Pool就可以了:

public class StringPool extends Pool{  public StringPool(){  }  public StringPool(final GenericObjectPoolConfig poolConfig,StringFactory factory){     super(poolConfig,factory);   }}

如下为获取资源的实例:

GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig ();        poolConfig.setMaxTotal(10);        StringFactory factory = new StringFactory();        StringPool pool =  new StringPool(poolConfig,factory);        for(int i=0;i<15;i++){            System.out.println(i+":");            String str = pool.getResource();            System.out.println(str);                    }        try {            pool.close();        } catch (IOException e) {            e.printStackTrace();        }

其运行结果如下:
这里写图片描述

测试一下释放资源的方法:

GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig ();        poolConfig.setMaxTotal(10);        StringFactory factory = new StringFactory();        StringPool pool =  new StringPool(poolConfig,factory);        for(int i=0;i<15;i++){            System.out.println(i+":");            String str = pool.getResource();            System.out.println(str);            pool.returnResourceObject(str);        }        try {            pool.close();        } catch (IOException e) {            e.printStackTrace();        }

其运行结果如下:
这里写图片描述

1 0
原创粉丝点击