等待超时模式在数据库连接池中的使用

来源:互联网 发布:测量图片尺寸软件 编辑:程序博客网 时间:2024/05/01 01:53

在常用的数据库连接池中就应用了等待超时模式,在代码示例中模拟从连接池中获取连接,使用和释放连接的过程。而客户端获取连接的过程被设定为等待超时的模式,

也就是在超时时间内如果无法获取到可用连接,将会返回一个null、设定连接池的数量为10个,然后通过条件客户端的线程数来模拟无法获取连接的场景。

public class ConnectionPool {    private LinkedList<Connection> pool = new LinkedList<Connection>();    private int initialSize = 10;    /**     * 初始化连接池     * @param initialSize     */    public ConnectionPool(int initialSize) {        if(initialSize > 0) {            this.initialSize = initialSize;        }        for(int i=0;i<initialSize;i++){            pool.addLast(ConnectionDriver.createConnection());        }    }    /**     * 释放连接池中的连接     * @param connection     */    public void releaseConnection(Connection connection){        if(connection != null){            synchronized (pool){                //连接放回连接池                pool.addLast(connection);                //连接放回连接池后,需要通知其他线程连接池中已经归还了一个连接,可以获取连接了                pool.notifyAll();            }        }    }    public Connection borrowConnection(long mills) throws InterruptedException{        synchronized (pool){            if(mills <= 0){                while (pool.isEmpty()){                    pool.wait();                }                return pool.removeFirst();            }else{                long future = System.currentTimeMillis() + mills;                long remaining = mills;                while (pool.isEmpty() && remaining > 0){                    pool.wait(remaining);                    remaining = future - System.currentTimeMillis();                }                Connection result = null;                if(!pool.isEmpty()){                    result = pool.removeFirst();                }                return result;            }        }    }}
public class ConnectionDriver {    /**     * 创建一个Connection的代理,在commit时休眠100毫秒     * @return     */    public static final Connection createConnection() {        return (Connection) Proxy.newProxyInstance(ConnectionDriver.class.getClassLoader(), new Class<?>[]{Connection.class}, new ConnectionHndler());    }    static class ConnectionHndler implements InvocationHandler {        @Override        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {            if (method.getName().equals("commit")) {                TimeUnit.MICROSECONDS.sleep(100);            }            return null;        }    }}

public class ConnectionPoolTest {    static ConnectionPool pool = new ConnectionPool(10);    //保证所有的ConnectionThread线程能够同时开始    static CountDownLatch start = new CountDownLatch(1);    static CountDownLatch end;    public static void main(String[] args) throws Exception{        int threadCount = 1000;        end = new CountDownLatch(threadCount);        int count = 20;        AtomicInteger got = new AtomicInteger();        AtomicInteger notGot = new AtomicInteger();        for(int i=0;i<threadCount;i++){            Thread thread = new Thread(new ConnectionThread(count,got,notGot),"ConnectionThread");            thread.start();        }        start.countDown();        end.await();        System.out.println("total invoke:"+(threadCount*count));        System.out.println("got coonection:"+got);        System.out.println("not got connection:"+notGot);    }    static class ConnectionThread implements Runnable{        int count;        AtomicInteger got;        AtomicInteger notGot;        public ConnectionThread(int count, AtomicInteger got, AtomicInteger notGot) {            this.count = count;            this.got = got;            this.notGot = notGot;        }        @Override        public void run() {            try {                start.await();            } catch (InterruptedException e) {                e.printStackTrace();            }            while (count > 0){                try {                    Connection connection = pool.borrowConnection(1000);                    if(connection != null){                        try {                            connection.createStatement();                            connection.commit();                        }finally {                            pool.releaseConnection(connection);                            got.incrementAndGet();                        }                    }else{                        notGot.incrementAndGet();                    }                } catch (Exception e) {                    e.printStackTrace();                }finally {                    count--;                }            }            end.countDown();        }    }}



0 0
原创粉丝点击