commons-pool2中GenericKeyedObjectPool应用demo

来源:互联网 发布:数据库质量控制 编辑:程序博客网 时间:2024/05/16 15:34

用commons-pool可以管理一些数据库连接池等东西,也可以结合动态代理实现自己的一些共有业务。

maven依赖:

<dependency>    <groupId>org.apache.commons</groupId>    <artifactId>commons-pool2</artifactId>    <version>2.4.1</version></dependency>
<dependency>    <groupId>junit</groupId>    <artifactId>junit</artifactId>    <version>4.10</version></dependency>

MyBean测试对象,对象池存管理该对象:

package littlehow.commons.demo.pool;import java.sql.Timestamp;/** * MyBean * * @author littlehow * @time 2016-05-27 11:11 */public class MyBean {    public static final String[] names = {"Littlehow", "Jim Green", "Black Tom", "White Cat", "Yellow Dog", "Color Wolf"};    /**     * bean被初始化的时间     */    private long instanceTime = System.currentTimeMillis();    /**     * 名称     */    private String name;    /**     * 对象是否存活     */    private boolean live = true;    /**     * 实例化对象     */    public MyBean () {        this.name = names[(int)(this.instanceTime % names.length)];    }    /**     * name由调用方指定     * @param name     */    public MyBean (String name) {        this.name = name;    }    /**     * 销毁方法     */    public void beKilled () {        System.out.print("我[" + this.name + "]居然被销毁了,我不甘心啊,");        System.out.println("就活了[" + (System.currentTimeMillis() - this.instanceTime) +"]毫秒!");    }    public String toString () {        return "我[" + this.name + "]出生在:" + new Timestamp(this.instanceTime);    }    /**     * 获取实例化时间     * @return     */    public long getInstanceTime () {        return this.instanceTime;    }    /**     * 获取对象标志     * @return     */    public String getName () {        return this.name;    }    /**     * 死亡掉     */    public void deadBean () {        this.live = false;    }    /**     * 人不是还活着     * @return     */    public boolean isLive () {        return this.live;    }    /**     * 相当于打开一个链接对象,如果是管理数据库连接的话     */    public void start () {        System.out.println(this.name + "的生命开始了");    }}

KeyPoolFactory对象池工厂

package littlehow.commons.demo.pool;import org.apache.commons.pool2.BaseKeyedPooledObjectFactory;import org.apache.commons.pool2.PooledObject;import org.apache.commons.pool2.impl.DefaultPooledObject;import org.apache.commons.pool2.impl.GenericKeyedObjectPool;import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;/** * KeyPoolFactory 带key的对象工厂 * * @author littlehow * @time 2016-05-27 11:28 */public class KeyPoolFactory {    /**     * 对象池     */    private static GenericKeyedObjectPool<String, MyBean> pool;    /**     * 对象池的参数设置     */    private static final GenericKeyedObjectPoolConfig config;    /**     * 对象池每个key最大实例化对象数     */    private final static int TOTAL_PERKEY = 10;    /**     * 对象池每个key最大的闲置对象数     */    private final static int IDLE_PERKEY = 3;    static {        config = new GenericKeyedObjectPoolConfig ();        config.setMaxTotalPerKey(TOTAL_PERKEY);        config.setMaxIdlePerKey(IDLE_PERKEY);        /** 支持jmx管理扩展 */        config.setJmxEnabled(true);        config.setJmxNamePrefix("myPoolProtocol");        /** 保证获取有效的池对象 */        config.setTestOnBorrow(true);        config.setTestOnReturn(true);    }    /**     * 从对象池中获取对象     * @param key     * @return     * @throws Exception     */    public static MyBean getBean (String key) throws Exception {        if (pool == null) {            init();        }        return pool.borrowObject(key);    }    /**     * 归还对象     * @param key     * @param bean     */    public static void returnBean (String key, MyBean bean) {        if (pool == null) {            init();        }        pool.returnObject(key , bean);    }    /**     * 关闭对象池     */    public synchronized static void close () {        if (pool !=null && !pool.isClosed()) {            pool.close();            pool = null;        }    }    /**     * 初始化对象池     */    private synchronized static void init () {        if (pool != null) return;        pool = new GenericKeyedObjectPool<String, MyBean>(new MyBeanPooledFactory(), config);    }    /**     * 对象工厂     */    static class MyBeanPooledFactory extends BaseKeyedPooledObjectFactory<String, MyBean> {        /**         * 创建对象         * @param key         * @return         * @throws Exception         */        public MyBean create(String key) throws Exception {            MyBean myBean = new MyBean();            myBean.start();            System.out.println(myBean);            return myBean;        }        public PooledObject<MyBean> wrap(MyBean value) {            return new DefaultPooledObject<MyBean>(value);        }        /**         * 验证对象是否有效         * @param key         * @param p         * @return         */        public boolean validateObject(String key, PooledObject<MyBean> p) {            MyBean bean = p.getObject();            if(!bean.isLive()){                System.out.println(bean.getName() + "已经死了,无法唤醒他了!");                return false;            }            return true;        }        /**         * 销毁         * @param key         * @param p         * @throws Exception         */        public void destroyObject(String key, PooledObject<MyBean> p)                throws Exception {            /** 杀死他 */            p.getObject().beKilled();        }        public void activateObject(String key, PooledObject<MyBean> p)                throws Exception {            super.activateObject(key, p);        }        public void passivateObject(String key, PooledObject<MyBean> p)                throws Exception {            super.passivateObject(key, p);        }    }}

GetBean测试类

package littlehow.commons.demo.pool;import org.junit.Test;import java.util.Random;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.LinkedBlockingDeque;import java.util.concurrent.TimeUnit;import static org.junit.Assert.*;/** * GetBean 测试从对象池中获取对象 * * @author littlehow * @time 2016-05-27 14:03 */public class GetBean {    static String[] keys = {"2016052700", "2016052800", "2016052900"};    /** 随机key */    Random r = new Random();    /**     * 获取key值     * @return     */    String getKey () {        return keys[r.nextInt(keys.length)];    }    /**     * 获取对象     */    @Test    public void getBean () {        String key = getKey();        /** 保证key值长度为10 */        assertTrue( "key的长度必须为10", key != null && key.length() == 10 );        try {            /**             * 同一个key最多可以获取10个对象             * 可以看出,当获取10个对象时,对象池就再也不能给出对象了             */            for (int i = 0; i < 20; i ++) {                TimeUnit.SECONDS.sleep(1);//睡一秒                KeyPoolFactory.getBean(key);            }            /** 可以看出拿对象时阻塞的 */            System.out.println("前方是否阻塞到我了...");        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 获取对象再还回去     */    @Test    public void getAndReturnBean () {        String key = getKey();        /** 保证key值长度为10 */        assertTrue( "key的长度必须为10", key != null && key.length() == 10 );        try {            /**             * 同一个key最多可以获取10个对象             * 可以看出,当获取10个对象时,对象池就再也不能给出对象了             */            for (int i = 0; i < 20; i ++) {                TimeUnit.SECONDS.sleep(1);//睡一秒                MyBean my = KeyPoolFactory.getBean(key);                /** 让对象死掉 */                my.deadBean();                /** 归还对象                 * 因为执行了my.deadBean(),这时候在归还对象时,他发现对象已经                 * 不合法了,这时候工厂就会重新拿对象                 * 如果屏蔽掉my.deadBean()这样的方法,那么获取到的对象将是第一次获取到的对象                 */                KeyPoolFactory.returnBean(key, my);            }        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 多个key同时去获取bean     */    @Test    public void getBeans () {        String key1 = getKey();        String key2 = key1;        while (key1.equals(key2)) {            key2 = getKey();        }        assertTrue( "key的长度必须为10,而获取到的key1="+key1, key1 != null && key1.length() == 10 );        assertTrue( "key的长度必须为10,而获取到的key2="+key2, key2 != null && key2.length() == 10 );        try {            /**             * 同一个key最多可以获取10个对象             * 20个对象用2个key就可以全部输出             * 这些都是不归还的             */            for (int i = 0; i < 20; i ++) {                TimeUnit.SECONDS.sleep(1);//睡一秒                if (i % 2 == 0){                    KeyPoolFactory.getBean(key1);                } else {                    KeyPoolFactory.getBean(key2);                }            }            /**             * 可以看出这句输出了             */            System.out.println("前方是否阻塞到我了...");        } catch (Exception e) {            e.printStackTrace();        }    }    /**     *  一个线程借对象,一个线程还对象     *  如果获取和归还的时间差特别大,会导致某些时候线程阻塞,因为对象已经拿完了     *  就好像借书一样,如果书被借完了,那么再想借就得需要等借书人还书了。     */    volatile boolean dead = false;//死亡对象标志    @Test    public void getAndReturnByThread () {        /** 对象缓存 */        final ConcurrentHashMap<String, LinkedBlockingDeque<MyBean>> beans = new ConcurrentHashMap<String, LinkedBlockingDeque<MyBean>>();        /**         * 借对象,每秒借一个         */        new Thread("borrow") {            public void run(){                while (true) {                    String key = getKey();                    LinkedBlockingDeque<MyBean> link = beans.get(key);                    if (link == null) {                        /** 最多存放10个对象 */                        link = new LinkedBlockingDeque<MyBean>(10);                        beans.put(key, link);                    }                    try {                        MyBean bean = KeyPoolFactory.getBean(key);                        link.push(bean);                        System.out.println(Thread.currentThread().getName() + "操作:key=" + key + ",bean=" + bean);                        TimeUnit.SECONDS.sleep(1);                    } catch (Exception e) {                        e.printStackTrace();                    }                }            }        }.start();        /**         * 还对象,每3秒还一个         */        new Thread("return") {            public void run () {                while (true) {                    String key = getKey();                    LinkedBlockingDeque<MyBean> link = beans.get(key);                    if (link == null || link.size() == 0) continue;                    /** 弹出元素 */                    MyBean bean = link.pop();                    if (dead) {                        bean.deadBean();                        dead = false;                    }                    System.out.println(Thread.currentThread().getName() + "操作:key="+key + ",bean="+bean);                    KeyPoolFactory.returnBean(key, bean);                    try {                        TimeUnit.SECONDS.sleep(3);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }.start();        /**         * 每5秒死亡一对象         */        new Thread("dead") {            public void run () {                while (true) {                    try {                        TimeUnit.SECONDS.sleep(5);                        dead = true;                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }.start();        try {            TimeUnit.MINUTES.sleep(5);//5分钟后结束程序            Runtime.getRuntime().exit(0);        } catch (Exception e) {        }    }}

1 0
原创粉丝点击