tags: Apache pool 对象池 引用:对象池,包括带key的
导入pom.xml
1 2 3 4 5 6
| <dependency> <groupId>commons-pool</groupId> <artifactId>commons-pool</artifactId> <version>1.6</version> </dependency>
|
注:这里的pool不是pool2
不带key的对象池
概述: factory对象实现PoolableObjectFactory
接口,完成其中的方法,可以在调用实例中将factory对象通过构造方法放入GenericObjectPool
或者StackObjectPool
测试对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class PoolTestObject {
private int num; private boolean active; private String uuid;
public PoolTestObject() { this.uuid = UUID.randomUUID().toString(); System.out.println("create a Object UUID:"+ uuid); } }
|
不带key的poolFactory
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class PoolTestFactory implements PoolableObjectFactory<PoolTestObject> {
@Override public PoolTestObject makeObject() throws Exception { PoolTestObject testPoolObject = new PoolTestObject(); System.out.println("创建对象,uuid:"+testPoolObject.getUuid()); return testPoolObject; }
@Override public void destroyObject(PoolTestObject testPoolObject) throws Exception { testPoolObject = null; System.out.println("摧毁对象!,uuid:"+testPoolObject.getUuid()); }
|
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
| @Override public boolean validateObject(PoolTestObject testPoolObject) { System.out.println("验证对象!,uuid:"+testPoolObject.getUuid()); if (testPoolObject.isActive()){ return true; }else { return false; } }
@Override public void activateObject(PoolTestObject testPoolObject) throws Exception { testPoolObject.setActive(true); System.out.println("激活对象!uuid:"+testPoolObject.getUuid()); }
@Override public void passivateObject(PoolTestObject testPoolObject) throws Exception { testPoolObject.setActive(false); System.out.println("钝化对象 uuid:"+testPoolObject.getUuid()); } }
|
验证(使用的引用中的例子,并做了点修改):
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 29 30 31 32 33 34 35 36 37 38 39 40 41
| @Test public void testPool(){ PoolTestObject bo = null; PoolableObjectFactory factory = new PoolTestFactory(); GenericObjectPool pool = new GenericObjectPool(factory); GenericObjectPool.Config config = new GenericObjectPool.Config(); config.maxActive = 5; pool.setConfig(config); try { for(int i = 0; i < 5; i++) { System.out.println("\n==========="+i+"==========="); System.out.println("池中处于闲置状态的实例pool.getNumIdle():"+pool.getNumIdle()); bo = (PoolTestObject)pool.borrowObject(); System.out.println(bo.getUuid()); bo.setUuid("-----------------------------------------1"); System.out.println("bo:"+bo); System.out.println(bo.getNum());; System.out.println("池中所有在用实例数量pool.getNumActive():"+pool.getNumActive()); if((i%2) == 0) { pool.returnObject(bo); System.out.println("归还对象!!!!"); } } } catch (Exception e) { e.printStackTrace(); } finally { try { if(bo != null) { pool.returnObject(bo); } pool.close(); } catch (Exception e) { e.printStackTrace(); } } }
|
调用结果,可以看到factory中的各个方法的执行过程,以及返回的对象如果做了修改,会保存这个修改,归还了对象之后,这个对象会回到池中作为空闲对象,下次borrow的时候,如果有空闲对象,会先调用空闲对象,如果没有空闲对象了,会调用makeObject
去自动创建对象
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| ===========0=========== 池中处于闲置状态的实例pool.getNumIdle():0 create a Object UUID:04ef2118-0b83-458c-b8e9-dc6d4b6548f8 创建对象,uuid:04ef2118-0b83-458c-b8e9-dc6d4b6548f8 激活对象!uuid:04ef2118-0b83-458c-b8e9-dc6d4b6548f8 04ef2118-0b83-458c-b8e9-dc6d4b6548f8 bo:cn.ws.apachepool.PoolTestObject@3d012ddd 0 池中所有在用实例数量pool.getNumActive():1 钝化对象 uuid:-----------------------------------------1 归还对象!!!!
===========1=========== 池中处于闲置状态的实例pool.getNumIdle():1 激活对象!uuid:-----------------------------------------1 -----------------------------------------1 bo:cn.ws.apachepool.PoolTestObject@3d012ddd 0 池中所有在用实例数量pool.getNumActive():1
===========2=========== 池中处于闲置状态的实例pool.getNumIdle():0 create a Object UUID:d979744b-fa76-4547-a34d-432e75049249 创建对象,uuid:d979744b-fa76-4547-a34d-432e75049249 激活对象!uuid:d979744b-fa76-4547-a34d-432e75049249 d979744b-fa76-4547-a34d-432e75049249 bo:cn.ws.apachepool.PoolTestObject@6f2b958e 0 池中所有在用实例数量pool.getNumActive():2 钝化对象 uuid:-----------------------------------------1 归还对象!!!!
===========3=========== 池中处于闲置状态的实例pool.getNumIdle():1 激活对象!uuid:-----------------------------------------1 -----------------------------------------1 bo:cn.ws.apachepool.PoolTestObject@6f2b958e 0 池中所有在用实例数量pool.getNumActive():2
===========4=========== 池中处于闲置状态的实例pool.getNumIdle():0 create a Object UUID:34bf5dce-6449-439c-ac92-5d26557d37b9 创建对象,uuid:34bf5dce-6449-439c-ac92-5d26557d37b9 激活对象!uuid:34bf5dce-6449-439c-ac92-5d26557d37b9 34bf5dce-6449-439c-ac92-5d26557d37b9 bo:cn.ws.apachepool.PoolTestObject@1eb44e46 0 池中所有在用实例数量pool.getNumActive():3 钝化对象 uuid:-----------------------------------------1 归还对象!!!! 钝化对象 uuid:-----------------------------------------1
|
GenericObjectPool
可以在创建了之后设置Cofig
可以查看设置的源码 具体参数如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public void setConfig(GenericObjectPool.Config conf) { synchronized(this) { this.setMaxIdle(conf.maxIdle); this.setMinIdle(conf.minIdle); this.setMaxActive(conf.maxActive); this.setMaxWait(conf.maxWait); this.setWhenExhaustedAction(conf.whenExhaustedAction); this.setTestOnBorrow(conf.testOnBorrow); this.setTestOnReturn(conf.testOnReturn); this.setTestWhileIdle(conf.testWhileIdle); this.setNumTestsPerEvictionRun(conf.numTestsPerEvictionRun); this.setMinEvictableIdleTimeMillis(conf.minEvictableIdleTimeMillis); this.setTimeBetweenEvictionRunsMillis(conf.timeBetweenEvictionRunsMillis); this.setSoftMinEvictableIdleTimeMillis(conf.softMinEvictableIdleTimeMillis); this.setLifo(conf.lifo); }
|
参数whenExhaustedA ction指定在池中借出对象的数目已达极限的情况下,调用它的borrowObject方法时的行为。可以选用的值有:
1 2 3
| GenericObjectPool.WHEN_EXHAUSTED_BLOCK,表示等待; GenericObjectPool.WHEN_EXHAUSTED_GROW,表示创建新的实例(不过这就使maxActive参数失去了意义); GenericObjectPool.WHEN_EXHAUSTED_FAIL,表示抛出一个java.util.NoSuchElementException异常。
|
带key的对象池
概述:factory对象实现KeyedPoolableObjectFactory
接口,完成其中的方法,可以在调用实例中将factory对象通过构造方法放入GenericKeyedObjectPool
可以通过keyPool.addObject("name");
往池中添加对象,也可以直接通过keyPool.borrow("name");
如果没有,会自动创建一个再借出来 带key的对象池和不带key的对象池区别在于可以通过key去取到特定的对象(在添加对象的时候回去设置key),具体参考引用
其他
还可以实现ObjectPool
接口,完成其中的方法,来自己定义一个Pool,这里的GenericObjectPool
就是实现了ObjectPool
接口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public interface ObjectPool<T> { T borrowObject() throws Exception, NoSuchElementException, IllegalStateException;
void returnObject(T var1) throws Exception;
void invalidateObject(T var1) throws Exception;
void addObject() throws Exception, IllegalStateException, UnsupportedOperationException;
int getNumIdle() throws UnsupportedOperationException;
int getNumActive() throws UnsupportedOperationException;
void clear() throws Exception, UnsupportedOperationException;
void close() throws Exception;
@Deprecated void setFactory(PoolableObjectFactory<T> var1) throws IllegalStateException, UnsupportedOperationException; }
|