common-pool2提供了3中對象池管理方式,它們的使用方式基本同樣,這裏以GenericObjectPool對象池爲例介紹其使用方式,通常實現本身的對象池須要通過2個步驟java
實現PooledObjectFactory接口:該接口是一種工廠模式,實現其目的是讓對象池經過該工廠模式建立管理的對象apache
建立對象池(GenericObjectPool(PooledObjectFactory))實例app
咱們假設Conn對象是一個創建TCP鏈接的對象,該對象的初始化時間平均爲500ms,爲了不在程序中頻繁建立Conn對象,咱們須要藉助對象池管理Conn對象實例ide
import org.slf4j.LoggerFactory; /** * common-pool2 使用方式 * <p/> * 假設這是一個創建TCP鏈接的對象,該對象的初始化時間平均爲500ms,爲了不在程序中頻繁建立Conn對象,咱們須要藉助對象池管理Conn對象實例 * * @author WangJun <wangjuntytl@163.com> * @version 1.0 15/10/28 * @since 1.6 */ public class Conn { /** * 記錄對象的建立時間 */ private long createTime; /** * 初始化Conn對象,模擬建立Conn對象平均消耗500ms * @throws InterruptedException */ public Conn() throws InterruptedException { Thread.sleep(500); createTime = System.currentTimeMillis(); LoggerFactory.getLogger(getClass()).debug(" init conn suc... " + createTime); } /** * 報告Conn對象信息 */ public void report() { LoggerFactory.getLogger(getClass()).info("this is a available conn " + createTime); } }
package com.peaceful.pool.demo; import org.apache.commons.pool2.BasePooledObjectFactory; import org.apache.commons.pool2.PooledObject; import org.apache.commons.pool2.PooledObjectFactory; import org.apache.commons.pool2.impl.DefaultPooledObject; /** * common-pool2 使用方式 * <p/> * 爲了使用common-pool2對象池管理,咱們必須實現{@link org.apache.commons.pool2.PooledObjectFactory}或者其子類 * 這是一個工廠模式,告訴對象池怎樣去建立要管理的對象 * <p/> * BasePooledObjectFactory 是對{@link org.apache.commons.pool2.PooledObjectFactory}的一個基本實現,咱們能夠繼承該類,減小一些方法的實現 * <p/> * 在實現{@link org.apache.commons.pool2.PooledObjectFactory}接口時,咱們必定要實現的接口方法是{@link PooledObjectFactory#makeObject()}方法。 * * @author WangJun <wangjuntytl@163.com> * @version 1.0 15/10/28 * @since 1.6 */ public class ConnFactory extends BasePooledObjectFactory<Conn> { /** * 間接實現{@link PooledObjectFactory#makeObject()}方法,代表怎樣建立須要管理對象 */ @Override public Conn create() throws Exception { return new Conn(); } /** * 在common-pool2中爲了統計管理的對象的一些信息,好比調用次數,空閒時間,上次使用時間等,須要對管理的對象進行包裝,而後在放入到對象池中 * * @param obj 對象池要管理的對象 * @return 返回包裝後的PooledObject對象 */ @Override public PooledObject<Conn> wrap(Conn obj) { return new DefaultPooledObject<Conn>(obj); } }
package com.peaceful.pool.demo; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; /** * common-pool2 使用方式 * <p/> * {@link org.apache.commons.pool2.impl.GenericObjectPool}支持個性化配置,咱們能夠配置對象池中總共的對象數,最大、最小空閒對象數等等 * 這邊繼承{@link GenericObjectPoolConfig}是爲了ConnPool也能夠進行個性化的配置 * * @author WangJun <wangjuntytl@163.com> * @version 1.0 15/10/28 * @since 1.6 */ public class ConnPoolConfig extends GenericObjectPoolConfig { public ConnPoolConfig() { // defaults to make your life with connection pool easier :) setMinIdle(5); setTestOnBorrow(true); } }
package com.peaceful.pool.demo; import org.apache.commons.pool2.impl.GenericObjectPool; /** * common-pool2 使用方式 * <p/> * Conn對象管理池,這裏利用GenericObjectPool做爲對象池 * * @author WangJun <wangjuntytl@163.com> * @version 1.0 15/10/28 * @since 1.6 */ public class ConnPool extends GenericObjectPool<Conn> { /** * 調用{@link GenericObjectPool}的構造方法,構造ConnPool */ public ConnPool() { super(new ConnFactory(), new ConnPoolConfig()); } /** * 調用{@link GenericObjectPool}的構造方法,構造ConnPool */ public ConnPool(ConnPoolConfig connPoolConfig) { super(new ConnFactory(), connPoolConfig); } }
public class ConnDemo { public static void main(String[] args) throws Exception { ConnPoolConfig connPoolConfig = new ConnPoolConfig(); connPoolConfig.setMinIdle(5); connPoolConfig.setMaxIdle(8); ConnPool connPool = new ConnPool(connPoolConfig); Conn conn1 = connPool.borrowObject(); Conn conn2 = connPool.borrowObject(); Conn conn3 = connPool.borrowObject(); Conn conn4 = connPool.borrowObject(); Conn conn5 = connPool.borrowObject(); conn1.report(); connPool.returnObject(conn1); conn2.report(); connPool.returnObject(conn2); conn3.report(); connPool.returnObject(conn3); conn4.report(); connPool.returnObject(conn4); conn5.report(); connPool.returnObject(conn5); conn5.report(); // 被歸還的對象的引用,不能夠在次歸還 // java.lang.IllegalStateException: Object has already been retured to this pool or is invalid try { connPool.returnObject(conn5); }catch (Exception e){ e.printStackTrace(); } } }
下面是ConnDemo的運行結果this
[2015-10-28 14:56:06 DEBUG] {com.peaceful.pool.demo.Conn:18}- init conn suc... [2015-10-28 14:56:07 DEBUG] {com.peaceful.pool.demo.Conn:18}- init conn suc... [2015-10-28 14:56:07 DEBUG] {com.peaceful.pool.demo.Conn:18}- init conn suc... [2015-10-28 14:56:08 DEBUG] {com.peaceful.pool.demo.Conn:18}- init conn suc... [2015-10-28 14:56:08 DEBUG] {com.peaceful.pool.demo.Conn:18}- init conn suc... [2015-10-28 14:56:08 INFO ] {com.peaceful.pool.demo.Conn:22}-this is a available conn 1446015366746 [2015-10-28 14:56:08 INFO ] {com.peaceful.pool.demo.Conn:22}-this is a available conn 1446015367346 [2015-10-28 14:56:08 INFO ] {com.peaceful.pool.demo.Conn:22}-this is a available conn 1446015367853 [2015-10-28 14:56:08 INFO ] {com.peaceful.pool.demo.Conn:22}-this is a available conn 1446015368354 [2015-10-28 14:56:08 INFO ] {com.peaceful.pool.demo.Conn:22}-this is a available conn 1446015368860 [2015-10-28 14:56:08 INFO ] {com.peaceful.pool.demo.Conn:22}-this is a available conn 1446015368860 java.lang.IllegalStateException: Object has already been retured to this pool or is invalid at org.apache.commons.pool2.impl.GenericObjectPool.returnObject(GenericObjectPool.java:595) at com.peaceful.pool.demo.ConnDemo.main(ConnDemo.java:37) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)