`

使用CGLIB实现JAVA对象连接池

    博客分类:
  • JAVA
阅读更多

使用CGLIB实现连接池

一、实现

1、线程工厂实现类:

=================================================================================

package com.wolf.pool;

import java.util.concurrent.ThreadFactory;

/**
* Author: jiyanbin
* Date: 下午1:28
* JDK: 1.7
*/
public class CommonThreadFactory implements ThreadFactory {
    private int threadCount = 0;
    private String prefix;
    private boolean daemon;

    public CommonThreadFactory(String prefix, boolean daemon) {
        this.prefix = prefix;
        this.daemon = daemon;
    }

    @Override
    public Thread newThread(Runnable r) {
        String name = prefix + threadCount++;
        Thread thread = new Thread(r, name);
        thread.setDaemon(daemon);
        return thread;
    }
}

================================================================================

2、被代理对象工厂接口

package com.wolf.pool;

/**
 * Author: jiyanbin
 * Date: 13-10-30:下午12:13
 * JDK: 1.7
 *
 * 业务对象工厂接口
 */
public interface Factory<T> {
    T newInstance();
}

================================================================================

3、资源池初始化接口

package com.wolf.pool;

/**
 * Author: jiyanbin
 * Date: 13-11-11:下午3:50
 * JDK: 1.7
 * 资源池初始化接口.
 *
 */
public interface Initial<T> {
    /**
     * 初始化资源池.
     *
     * <p/>
     * 初始化资源池,比如:根据初始池大小创建资源等。
     */
    void initial();
}

================================================================================

4、简单公用的对像池,提供超时回收机制

package com.wolf.pool;

import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Author: jiyanbin
 * Date: 13-10-30:上午10:29
 * JDK: 1.7
 * <p/>
 * 一个简单公用的对像池,提供超时回收机制。
 * <p/>
 * <p/>
 * 連接池特性:
 * <li>支持初始池大小配置,默认值为:2</li>
 * <li>支持最大池大小配置,默认值为:5</li>
 * <li>支持最大空闲数配置,默认值为:3</li>
 * <li>支持当资源不足,且未到达最大值时,批量创建的资源个数配置,默认值为:2</li>
 * <li>支持当资源不足,且未到达最大值时,批量创建资源的任务数配置,默认值为:1</li>
 * <li>支持最大空闲时间配置,默认值为:3分钟</li>
 * <li>支持最大超时时间配置,默认值为:3分钟</li>
 * <li>支持空闲资源回收周期配置,默认值为:1分钟</li>
 * <p/>
 * <p/>
 * 此连接池需要通过{@link SimpleResourcePool.SimpleResourcePoolBuilder#build()}创建,如:
 * {@code SimpleResourcePool.SimpleResourcePoolBuilder<SimpleObject> builder = new SimpleResourcePool.SimpleResourcePoolBuilder<SimpleObject>( new SimpleObjectFactory());
 * builder.setInitSize(2).setIdleSize(5)。。。。;
 * SimpleResourcePool pool = builder.build(); }
 * <p/>
 * <p/>
 * 资源池构建成功后,需要调用{@code pool.initial();}进行资源池启动初始化。
 * <p/>
 * <p/>
 * 构建{@link SimpleResourcePool.SimpleResourcePoolBuilder}对象,需要提供{@link Factory}工厂实现,此factory是真实业务对象的工厂。
 * <p/>
 * <p/>
 * 业务对象说明:
 * <li>业务对象有默认构造器</li>
 * <p/>
 * {@link SimpleResourcePool.SimpleResourcePoolBuilder#proxyedConstructorArgumentsType}与{@link SimpleResourcePool.SimpleResourcePoolBuilder#proxyedArguments}可以不用设置。
 * <p/>
 * <p/>
 * <li>业务对象无默认构造器</li>
 * <p/>
 * {@link SimpleResourcePool.SimpleResourcePoolBuilder#proxyedConstructorArgumentsType}与{@link SimpleResourcePool.SimpleResourcePoolBuilder#proxyedArguments}必须用设置,此参数类型及值的顺序与业务类构造器相同。
 * <p/>
 * <p/>
 * <p/>
 * 并发问题说明:
 * <p/>
 * <li>资源回收与资原分配</li>
 * <p/>
 * 当池并发访问量大时,此时池在有空闲对象,而同时,回收空闲资源的任务有可能将池中资源作有空闲资源回收,但此资源又分配给工作任务,在用户任务结束后,此资源作为有效资源check in pool,
 * 此种形为认为是合法的,回收空闲资源的任务具有较低优先级,以防止资源被重复回收并重建,这在资源实例创建需要较高成本时,对性能影响较大。
 */
public class SimpleResourcePool<T> implements Initial<T> {
    private int initSize;
    private int maxSize;
    private int batchSize;
    private int batchTaskCount;
    private int idleSize;
    private long maxIdleTime;
    private long idleResourceTestCycle;

    private Semaphore available;
    private Class[] proxyedConstructorArgumentsType;
    private Object[] proxyedArguments;
    private Factory<T> factory;

    private BlockingQueue<ResourceWrapper<T>> resources;
    private final List<ResourceWrapper<T>> checked = new CopyOnWriteArrayList<ResourceWrapper<T>>();
    private ExecutorService fillPoolService;

    @Override
    public void initial() {
        available = new Semaphore(maxSize, true);
        resources = new LinkedBlockingQueue<ResourceWrapper<T>>(maxSize);
        fillPoolService = Executors.newFixedThreadPool(batchTaskCount, new CommonThreadFactory("FillResourcePoolThread-", false));
        for (int i = 0; i < this.initSize; ++i) {
            T proxyed = factory.newInstance();
            ResourceWrapper<T> wrapper = new ResourceWrapper<T>(proxyed, proxyedConstructorArgumentsType, proxyedArguments);
            resources.add(wrapper);
        }
        ResourcePoolManage manage = new ResourcePoolManage(idleResourceTestCycle);
        manage.setPool(this);
        manage.start();
    }

    private SimpleResourcePool() {
    }

    public int getInitSize() {
        return initSize;
    }

    public int getMaxSize() {
        return maxSize;
    }

    public int getBatchSize() {
        return batchSize;
    }

    public int getIdleSize() {
        return idleSize;
    }

    public long getMaxIdleTime() {
        return maxIdleTime;
    }

    public BlockingQueue<ResourceWrapper<T>> getResources() {
        return resources;
    }

    public List<ResourceWrapper<T>> getChecked() {
        return new CopyOnWriteArrayList<ResourceWrapper<T>>(checked);
    }

    /**
     * 当前池中有效的资源数.
     * <p/>
     * <p/>
     * 此方法返回的是理论值,即:根据{@link SimpleResourcePool#maxSize}属性所计算。此时池中可能并没有返回值所指定的有效对象,需要池动态创建.
     * 比如:此方法返回5,则说明{@link SimpleResourcePool#available}还剩余5次有效访问。但是池中有可能只有2个对象,需要由池动态创建。但最多
     * 不会超过{@link SimpleResourcePool#maxSize}属性所指定的值.
     * <p/>
     *
     * @return 池中余下的有效许可.
     */
    public int getAvailableObjectSize() {
        return available.availablePermits();
    }

    /**
     * 签出对象
     * <p/>
     * 当没有空闲对象时,等待timeout指定的时间,超时后,还没获得所需对象,则被中断。
     * <p/>
     * <p/>
     * 最坏的情况下,会等待 2 * timeout的时间。
     * 分别是:
     * <li>分配许可等待了timeout所指定的时间</li>
     * <li>许可拿到后,从池中获取资源等待了timeout所指定的时间</li>
     *
     * @param timeout  超时时间
     * @param timeUnit 超时单位
     * @return
     * @throws Exception 当在timeout指定的时间内没有可用对象,则抛出异常
     */
    public T checkout(long timeout, TimeUnit timeUnit) {
        try {
            available.tryAcquire(timeout, timeUnit);
            return getItem(timeout, timeUnit);
        } catch (Exception e) {
            e.printStackTrace();
            throw new IllegalStateException("Can not get object from pool!", e);
        }
    }

    /**
     * 签出对象
     * <p/>
     * 一直等待,直到有可用对象.
     * <p/>
     * <p/>
     * 此方法在极端的情况下,可能会挂死工作任务。就是在池的压力过大时,工作任务一直没有拿到可用资源。
     * 由客户端通过中断方式取消资源获取.
     * </p>
     *
     * @return
     * @throws Exception 线程中断时抛出.
     */
    public T checkout() {
        try {
            available.acquire();
            return getItem(Long.MAX_VALUE, TimeUnit.SECONDS);
        } catch (Exception e) {
            throw new IllegalStateException("Can not get object from pool!", e);
        }
    }

    /**
     * 释放对象
     *
     * @param item
     */
    public void release(T item) {
        if (_release(item)) {
            available.release();
        }
    }

    private final AtomicInteger checkoutTimes = new AtomicInteger(0);

    public AtomicInteger getCheckoutTimes() {
        return new AtomicInteger(checkoutTimes.get());
    }

    private T getItem(long timeout, TimeUnit timeUnit) throws Exception {
        //get resource from pool at first.
        ResourceWrapper<T> wrapper = resources.poll();
        //if pool is null
        if (wrapper == null) {
            // fill pool according maxSize, this will be start some async task to create resource.
            fillResources();
            // wait unit there is an resource return or timeout.
            wrapper = resources.poll(timeout, timeUnit);
            if (wrapper == null) {
                // timeout, return null resource
                throw new IllegalStateException("Can not checkout object from pool!");
            }
        }
        checkoutTimes.incrementAndGet();
        checked.add(wrapper);
        return wrapper.checkout();
    }

    private boolean _release(T item) {
        for (ResourceWrapper<T> wrapper : checked) {
            //支持一个线程同时持有多个资源时,释放某一个资源。
            if (wrapper.release(item)) {
                try {
                    lock.lock();
                    resources.offer(wrapper);
                    checkoutTimes.decrementAndGet();
                    checked.remove(wrapper);
                    return true;
                } finally {
                    lock.unlock();
                }
            }
        }
        return false;
    }

    private void fillResources() throws Exception {
        for (int i = 0; i < batchSize; i++) {
            fillPoolService.submit(new FillPoolTask());
        }
    }

    public String toString() {
        return "SimpleResourcePool: {\n" +
                "initSize              =" + initSize + "\n" +
                "maxSize               =" + maxSize + "\n" +
                "batchSize             =" + batchSize + "\n" +
                "batchTaskCount        =" + batchTaskCount + "\n" +
                "idleSize              =" + idleSize + "\n" +
                "maxIdleTime           =" + maxIdleTime + "\n" +
                "idleResourceTestCycle =" + idleResourceTestCycle + "\n" +
                "}";

    }

    private Lock lock = new ReentrantLock(true);

    public class FillPoolTask implements Callable<ResourceWrapper<T>> {
        @Override
        public ResourceWrapper<T> call() {
            if (resources.size() + checkoutTimes.get() < maxSize) {
                T proxyed = factory.newInstance();
                //业务对象的创建有可能很耗时,所以此处使用双重判断加锁模式,先创建来务对象包装器
                ResourceWrapper<T> wrapper = new ResourceWrapper<T>(proxyed, proxyedConstructorArgumentsType, proxyedArguments);
                try {
                    lock.lock();
                    if (resources.size() + checkoutTimes.get() < maxSize) {
                        resources.add(wrapper);
                        System.out.println(Thread.currentThread().getName() + " create new resource! Pool size [" + (resources.size() + checkoutTimes.get()) + "]");
                        return wrapper;
                    }
                } finally {
                    lock.unlock();
                }
            }
            return null;
        }
    }

    public static class SimpleResourcePoolBuilder<T> {
        /**
         * 池中目标对象类型
         */
        //private final Class<T> clazz;
        /**
         * 被代理类参构造器参数类型数据,根构造器参数声明顺序一至.
         */
        private Class[] proxyedConstructorArgumentsType = new Class[0];
        /**
         * 被代理對象constructor arguments
         */
        private Object[] proxyedArguments = new Object[0];

        /**
         * 真正的业务对像工厂,非代理对象.
         */
        private final Factory<T> factory;
        /**
         * 池的初始大小
         */
        private int initSize = 2;
        /**
         * 池的最大容量
         */
        private int maxSize = 5;
        /**
         * 当资源不足,且未到达最大值时,批量创建的资源个数
         */
        private int batchSize = 2;
        /**
         * 当资源不足,且未到达最大值时,批量创建的资源的任务数
         */
        private int batchTaskCount = 1;
        /**
         * 允许池中对象的空闲数
         */
        private int idleSize = 3;
        /**
         * 最大空闲时间,超过此空闲时的池对象,将被释放
         */
        private long maxIdleTime = 3 * 60 * 1000;
        /**
         * 对象有效时间,即:如果分配出去的池对象,在这个时间内没有被使用,则从当前线程中强制释放,放入线程池
         */
        //private long timeout = 3 * 60 * 1000;
        /**
         * 回收idle对象的线程周期,单位ms;
         */
        private long idleResourceTestCycle = 60 * 1000;

        /**
         * 回收timeout对象的线程周期,单位ms;
         */
        //private long timeoutCycle = 60 * 1000;
        public SimpleResourcePoolBuilder(Factory<T> factory) {
            this.factory = factory;
        }

        public SimpleResourcePoolBuilder setInitSize(int initSize) {
            if (initSize < 0) {
                throw new IllegalArgumentException("initSize must greater than 0!");
            }
            if (initSize > 0)
                this.initSize = initSize;
            return this;
        }

        public SimpleResourcePoolBuilder setMaxSize(int maxSize) {
            if (maxSize < 0) {
                throw new IllegalArgumentException("maxSize must greater than 0!");
            }
            if (maxSize > 0)
                this.maxSize = maxSize;
            return this;
        }

        public SimpleResourcePoolBuilder setBatchSize(int batchSize) {
            if (batchSize < 0) {
                throw new IllegalArgumentException("batchSize must greater than 0!");
            }
            if (batchSize > 0)
                this.batchSize = batchSize;
            return this;
        }

        public SimpleResourcePoolBuilder setBatchTaskCount(int batchTaskCount) {
            if (batchTaskCount < 0) {
                throw new IllegalArgumentException("batchTaskCount must greater than 0!");
            }
            if (batchTaskCount > 0)
                this.batchTaskCount = batchTaskCount;
            return this;
        }

        public SimpleResourcePoolBuilder setIdleSize(int idleSize) {
            if (idleSize < 0) {
                throw new IllegalArgumentException("idleSize must greater than 0!");
            }
            if (idleSize > 0)
                this.idleSize = idleSize;
            return this;
        }

        public SimpleResourcePoolBuilder setMaxIdleTime(long maxIdleTime) {
            if (maxIdleTime < 0) {
                throw new IllegalArgumentException("maxIdleTime must greater than 0!");
            }
            if (maxIdleTime > 0)
                this.maxIdleTime = maxIdleTime;
            return this;
        }

        public SimpleResourcePoolBuilder setIdleResourceTestCycle(long idleResourceTestCycle) {
            if (idleResourceTestCycle < 0) {
                throw new IllegalArgumentException("idleResourceTestCycle must greater than 0!");
            }
            if (idleResourceTestCycle > 0)
                this.idleResourceTestCycle = idleResourceTestCycle;
            return this;
        }

        public SimpleResourcePoolBuilder setProxyedConstructorArgumentsType(Class[] proxyedConstructorArgumentsType) {
            if (proxyedConstructorArgumentsType == null) {
                proxyedConstructorArgumentsType = new Class[0];
            }
            this.proxyedConstructorArgumentsType = proxyedConstructorArgumentsType;
            return this;
        }

        public SimpleResourcePoolBuilder setProxyedArguments(Object[] proxyedArguments) {
            if (proxyedArguments == null) {
                proxyedArguments = new Object[0];
            }
            this.proxyedArguments = proxyedArguments;
            return this;
        }

        public SimpleResourcePool<T> build() {
            SimpleResourcePool<T> pool = new SimpleResourcePool<T>();
            pool.initSize = initSize;
            pool.batchSize = batchSize;
            pool.batchTaskCount = batchTaskCount;
            pool.idleSize = idleSize;
            pool.maxIdleTime = maxIdleTime;
            pool.idleResourceTestCycle = idleResourceTestCycle;
            pool.maxSize = maxSize;
            pool.factory = factory;
            pool.proxyedConstructorArgumentsType = proxyedConstructorArgumentsType;
            pool.proxyedArguments = proxyedArguments;
            return pool;
        }
    }
}

================================================================================

5、动态代理包装器

package com.wolf.pool;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * Author: jiyanbin
 * Date: 13-11-11:上午10:00
 * JDK: 1.7
 * <p/>
 * 动态代理包装器.
 * <p/>
 * 资源对象的包装器,有些资源可能属于第三方实现,通过此包装器装饰,此包装器采用CGLIB实现,对目标对象的访问都要先通过此包装器生成的代理对象进行验证。
 * 此包装器持有CGLIB生成的代理对象及业务对象引用。
 */
public class ResourceWrapper<T> implements MethodInterceptor {
    private Thread currentHolder;
    private long checkoutTime;
    private long checkInTime;
    private boolean isCheckout;
    //proxy object
    private T proxy;
    //target object, create by Factory
    private T proxyed;
    private Class[] proxyedConstructorArgumentsType;
    private Object[] proxyedArguments;

    public ResourceWrapper(T proxyed, Class[] argumentsType, Object[] arguments) {
        this.proxyed = proxyed;
        proxyedConstructorArgumentsType = argumentsType;
        proxyedArguments = arguments;
        newProxy();
    }

    public Thread getCurrentHolder() {
        return currentHolder;
    }

    public void setCurrentHolder(Thread currentHolder) {
        this.currentHolder = currentHolder;
    }

    public long getCheckoutTime() {
        return checkoutTime;
    }

    public void setCheckoutTime(long checkoutTime) {
        this.checkoutTime = checkoutTime;
    }

    public boolean isCheckout() {
        return isCheckout;
    }

    public void setCheckout(boolean checkout) {
        isCheckout = checkout;
    }

    public long getCheckInTime() {
        return checkInTime;
    }

    public void setCheckInTime(long checkInTime) {
        this.checkInTime = checkInTime;
    }

    public T getProxy() {
        return proxy;
    }

    /**
     * release the given proxy object.
     * <p/>
     * if this wrapper's proxy reference equals the given proxy object {@code if (getCurrentHolder() == Thread.currentThread() && item == proxy)},
     * and this wrapper has been checked out, release it.
     *
     * @param item
     * @return
     */
    public boolean release(T item) {
        if (getCurrentHolder() == Thread.currentThread() && item == proxy) {
            setCheckout(false);
            setCurrentHolder(null);
            setCheckoutTime(0L);
            setCheckInTime(System.currentTimeMillis());
            return true;
        }
        return false;
    }

    /**
     * checkout proxy object.
     *
     * @return if this proxy has been checked out, return false, or else return true;
     */
    public T checkout() {
        if (!isCheckout) {
            setCheckout(true);
            setCheckoutTime(System.currentTimeMillis());
            setCurrentHolder(Thread.currentThread());
            return proxy;
        }
        return null;
    }

    /**
     * 验证代理对象是否还被当前线程所持有
     *
     * @return 代理对象被回收,返回false
     */
    public boolean access() {
        return currentHolder == Thread.currentThread();
    }

    /**
     * CGLIB拦截器方法.
     * <p/>
     *
     * @param o
     * @param method
     * @param objects
     * @param methodProxy
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        if (access()) {
            return method.invoke(proxyed, objects);
        } else {
            throw new RuntimeException("Resource has been released!");
        }
    }

    /**
     * 创建代理对象.
     * <p/>
     *
     * @return
     */
    private T newProxy() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(proxyed.getClass());
        enhancer.setCallback(this);
        // 创建代理对象
        return proxy = (T) enhancer.create(proxyedConstructorArgumentsType, proxyedArguments);
    }
}

================================================================================

6、资源池管理器,用于资源池的运行时管理

package com.wolf.pool;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * Author: jiyanbin
 * Date: 13-11-11:下午3:08
 * JDK: 1.7
 * 资源池管理器,用于资源池的运行时管理。
 * <p/>
 * <p/>
 * 包括以下功能:
 * <li>根据资源池的配置,回收空闲时间超过配置的资源,使池保持idle所配置的资源数,此处的回收是将多余资源释放</li>
 */
public class ResourcePoolManage<T> {

    private SimpleResourcePool<T> pool;
    /**
     * 回收idle对象的线程周期,单位ms;
     */
    private long idleCycle;

    public ResourcePoolManage(long idleCycle) {
        this.idleCycle = idleCycle;
    }

    public void start() {
        ScheduledExecutorService service = new ScheduledThreadPoolExecutor(1, new CommonThreadFactory("ResourceRetrieveThread-", false));
        service.scheduleWithFixedDelay(new ResourceRetrieveTask(), idleCycle, idleCycle, TimeUnit.MILLISECONDS);
    }

    public SimpleResourcePool<T> getPool() {
        return pool;
    }

    public void setPool(SimpleResourcePool<T> pool) {
        this.pool = pool;
    }

    /**
     * 回收空闲的资源.
     * <p/>
     * 只有在队列里的,才是没有被签出的,才有可能是idle的。此处不用同步,为了性能,在大并发时,可能会存在资源被签出,但同时也被回收的情况。
     * 此种情况在客户使用完资源放到池中时,已被回收的资源,将会重新回到池中。
     * @see SimpleResourcePool
     */
    private class ResourceRetrieveTask implements Runnable {
        @Override
        public void run() {
            int idle = 0;
            int count = 0;
            List<ResourceWrapper<T>> temp = new ArrayList<ResourceWrapper<T>>();
            //此处的统计不严格正确。要严格正确,需要线程同步,影响性能。这个地方不影响大局,不用较真。都是出来混的,何必呢,累!
            for (ResourceWrapper<T> wrapper : pool.getResources()) {
                if (!wrapper.isCheckout()) {
                    if (System.currentTimeMillis() > wrapper.getCheckInTime() + pool.getMaxIdleTime()) {
                        if (++idle > pool.getIdleSize()) {
                            temp.add(wrapper);
                            count++;
                        }
                    }
                }
            }
            pool.getResources().removeAll(temp);
            //当你发现此处的输出:checkout size + pool size > maxSize时,不用担心,也无需害怕。正常现象:-)
            System.out.println("Remove [" + count + "] objects from pool. Checkout size is: ["+pool.getCheckoutTimes().get()+"] Pool size is :[" + pool.getResources().size()+ "]");
        }
    }

}

================================================================================

二、测试

================================================================================

package com.wolf.pool;

import java.util.concurrent.TimeUnit;

/**
 * Author: jiyanbin
 * Date: 下午12:48
 * JDK: 1.7
 */
public class SimpleObject {
    private String text;

    public SimpleObject(String text) {
        /*try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/
        this.text = text;
    }

    /*public SimpleObject() {
    }*/

    public void setText(String text) {
        this.text = text;
    }

    public void printString(String context){
        //System.out.println("SimpleObject context is :["+context+"], text is: ["+text+"]");
    }
}

================================================================================

package com.wolf.pool;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Author: jiyanbin
 * Date: 上午10:35
 * JDK: 1.7
 */
public class SimpleResourcePoolTest {
    static SimpleResourcePool<SimpleObject> pool = null;

    public static void main(String[] args) {
        SimpleResourcePool.SimpleResourcePoolBuilder<SimpleObject> builder = new SimpleResourcePool.SimpleResourcePoolBuilder<SimpleObject>(new SimpleObjectFactory());
        builder.setInitSize(1)
                .setIdleSize(2)
                .setBatchSize(3)
                .setBatchTaskCount(3)
                .setMaxIdleTime(30 * 1000)
                .setIdleResourceTestCycle(5 * 1000)
                .setMaxSize(10)
                .setProxyedConstructorArgumentsType(new Class[]{String.class})
                .setProxyedArguments(new String[]{null});
        pool = builder.build();
        pool.initial();
        System.out.println(pool.toString());

        ExecutorService service = Executors.newCachedThreadPool(new CommonThreadFactory("TestThread-",false));
        for (int i = 0; i < 50; i++) {
            service.execute(new NormalTask());
        }
    }

    public static class NormalTask implements Runnable {
        @Override
        public void run() {
            Random random = new Random(0);
            while (true) {
                SimpleObject object = null;
                try {
                    //object = pool.checkout(60, TimeUnit.SECONDS);
                    object = pool.checkout();
                    //System.out.println("After "+Thread.currentThread().getName() +" checkout resource, Pool available size [" + pool.getAvailableObjectSize() + "]");
                    //TimeUnit.SECONDS.sleep(1);
                    object.printString(Thread.currentThread().getName());
                    try {
                        //TimeUnit.MILLISECONDS.sleep(random.nextInt(500));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (object != null) {
                        pool.release(object);
                        // after release, invoke proxy object method will throw Exception
                        //object.printString(Thread.currentThread().getName());
                        //System.out.println("After "+Thread.currentThread().getName() +" release resource, Pool available size [" + pool.getAvailableObjectSize() + "]");
                    }
                }

            }

        }
    }

    public static class SimpleObjectFactory implements Factory<SimpleObject> {
        @Override
        public SimpleObject newInstance() {
            return new SimpleObject("abc");
        }
    }
}

================================================================================

分享到:
评论

相关推荐

    JDBC数据库连接池的简单实现.rar

    3. 使用连接池:在Java代码中,可以通过@Autowired注解注入DataSource,然后通过DataSource获取Connection对象进行数据库操作。例如: ```java @Autowired private DataSource dataSource; public void executeSQL...

    JAVA数据库连接池proxool

    在Proxool中,CGLIB可能用于创建数据库连接的代理对象,以实现透明的连接池管理。`proxool-0.9.1.jar`则是Proxool的主要实现库,包含了所有连接池管理的类和方法。 使用Proxool时,开发者需要配置一个XML配置文件,...

    java红数据连接池包下载

    在Proxool中,CGLIB可能用于创建数据库连接的代理对象,以实现连接池的功能。 2. `proxool-0.9.1.jar`:这是Proxool的主要库文件,包含了连接池的实现和相关的API。 3. `commons-logging-1.0.4.jar`:这是Apache ...

    java连接池文件及lib

    1. **Proxool连接池**:Proxool是一个开源的Java数据库连接池实现,它提供了一种轻量级的方式管理数据库连接。`proxool-0.9.1.jar`是Proxool的核心库,用于创建和维护数据库连接池。`ProxoolConf.xml`是Proxool的...

    Proxool连接池jar包

    总的来说,Proxool连接池提供了一种轻量级、易于使用的数据库连接管理方案,能够有效提高Java应用程序处理数据库的能力,降低系统资源的消耗,同时通过监控和统计功能帮助我们更好地理解和优化系统性能。在选择和...

    proxool-0.9.1.jar proxool_cglib-0.9.1.jar

    "proxool-0.9.1.jar" 和 "proxool_cglib-0.9.1.jar" 是针对数据库连接池的Java库,其中Proxool负责管理数据库连接,而CGLIB提供了动态代理功能,帮助实现Proxool的核心功能。这两个库的使用需要配置合适的参数以适应...

    proxool+mysql+tomcat连接池所需jar包

    在构建企业级Java应用时,连接池是必不可少的组件,它优化了数据库连接的管理和复用,提高了系统性能。本文将详细介绍"proxool+mysql+tomcat连接池所需jar包"的相关知识,以及如何在实际项目中配置和使用。 首先,...

    proxool-0.6.jar proxool-cglib.jar

    在Proxool中,CGLIB可能被用来动态生成数据库连接的代理对象,以实现透明的连接池操作。通过这种方式,Proxool可以在不修改用户代码的情况下,拦截数据库连接的创建和关闭操作,将实际的物理连接操作替换为从连接池...

    proxool连接池

    2. **创建连接池**:使用`orgproxoolSqlPoolDataSource`类创建数据源对象,然后根据配置信息初始化。 3. **获取连接**:通过数据源对象的`getConnection()`方法获取数据库连接。 4. **关闭连接**:使用完数据库连接...

    hibernate连接池驱动

    Proxool也是一个开源的JDBC连接池,它通过创建连接池的“影子”连接来实现,这意味着即使数据库连接已经被使用,Proxool也能创建虚拟的连接供其他线程使用,从而提高并发性能。配置Proxool与Hibernate的集成,同样...

    proxool连接池所需的jar包

    总结,Proxool连接池是Java应用中的一个高效数据库连接管理工具,通过proxool-0.9.1.jar和proxool-cglib.jar这两个jar包,开发者可以轻松地集成和使用Proxool,从而优化数据库访问性能,提升系统的整体效率。...

    c3p0-0.9.0 cglib-2.2 cglib-nodep-2.2

    `c3p0`是一个开源的JDBC连接池,而`cglib`则是一个强大的Java代码生成库。让我们深入探讨这两个组件及其在软件开发中的作用。 首先,`c3p0-0.9.0`是c3p0连接池的一个版本。c3p0是一个流行的、完全兼容JDBC的数据库...

    Java实现动态代理

    - 类似地,连接池工具包(如`connect类工具包`)可能也会使用动态代理来封装数据库连接的获取与释放,以实现更高效的资源管理。 4. **性能考虑**: - 虽然动态代理提供了强大的功能,但它的性能相对较低,因为...

    proxool开发包

    其中,"proxool-cglib.jar"可能包含了CGLIB(Code Generation Library)的支持,这是一个强大的Java字节码处理框架,常用于动态代理、AOP(面向切面编程)等领域,可能在Proxool中用于动态生成代理类以实现连接池的...

    proxool-0.9.1

    Proxool 是一个开源的 Java 数据库连接池实现,它提供了一种高效且灵活的方式来管理数据库连接。在 Java 应用程序中,数据库连接池是优化性能的关键组件,它通过重用已建立的数据库连接来减少资源消耗,提高系统响应...

    代码性能Java比较

    1. **单例模式**:保证一个类只有一个实例,常用于配置类或者数据库连接池。Java中可以使用双重检查锁定或静态内部类实现线程安全的单例。 2. **工厂模式**:提供一个接口来创建对象,但让子类决定实例化哪一个类。...

    proxool jar包

    总的来说,proxool是一个强大的数据库连接池实现,特别是在与Hibernate等ORM框架配合使用时,能提供高效、稳定的数据库连接管理。尽管现代开发中已经有了如HikariCP、Druid等更先进的连接池,但理解proxool的工作...

    java常用的jar包

    9. **Hibernate**:Hibernate是一个对象关系映射(ORM)框架,它允许Java开发者使用面向对象的方式来操作数据库。Hibernate通过映射Java类到数据库表,自动处理SQL语句,简化了数据库访问,提高了开发效率。 以上jar...

    proxool-0.9.1.jar

    4. **Java代理机制**:代理类可以拦截方法调用,实现如事务管理、性能监控等功能,而CGLib是实现Java动态代理的一种方式,尤其在不能使用接口的情况下。 5. **项目构建和依赖管理**:在Java项目中,"lib"目录下的JAR...

Global site tag (gtag.js) - Google Analytics