一个简单的数据库连接池实例

来源:互联网 发布:淘宝直通车效果怎么样 编辑:程序博客网 时间:2024/06/11 19:50

使用等待超时模式来构造一个简单的数据库连接池,实例中模拟从连接池中获取、使用和释放连接的过程,而客户端获取连接的过程被设定为等待超时的模式,也就是在1000毫秒内如果无法获取到可用连接,将会返回给客户端一个null。通过调节线程来模拟无法获取连接的场景。

代码清单如下:

ConnectionPool .java

package com.enfo.wd;import java.sql.Connection;import java.util.LinkedList;public class ConnectionPool {    private LinkedList<Connection> pool=new LinkedList<Connection>();    public ConnectionPool(int initialSize){        if(initialSize>0){            for(int i=0;i<initialSize;i++){                pool.addLast(ConnectionDriver.createConnection());            }        }    }    public void releaseConnection(Connection connection){        if(connection!=null){            synchronized (pool) {                //连接释放后需要进行通知,这样其他消费者能够感知到连接池中已经归还了一个连接                pool.addLast(connection);                pool.notifyAll();            }        }    }    //在mills内无法获取到连接,将会返回null    public Connection fetchConnection(long mills)throws Exception{        //完全超时        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;        }    }}

ConnectionDriver .java

package com.enfo.wd;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.sql.Connection;import java.util.concurrent.TimeUnit;public class ConnectionDriver {    static class ConnectionHandler implements InvocationHandler{        public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{            if(method.getName().equals("commit")){                TimeUnit.MILLISECONDS.sleep(100);            }            return null;        }    }    //创建一个connection的代理,在commit时休眠100毫秒    public static final Connection createConnection() {        return (Connection) Proxy.newProxyInstance(ConnectionDriver.class.getClassLoader(), new Class<?>[]{Connection.class},new ConnectionHandler());    }}

ConnectionTest .java

package com.enfo.wd;import java.sql.Connection;import java.util.concurrent.CountDownLatch;import java.util.concurrent.atomic.AtomicInteger;public class ConnectionTest {    static ConnectionPool pool=new ConnectionPool(10);    //保证所有的ConnetionRunner 能够同时开始    static CountDownLatch start=new CountDownLatch(1);    //mine线程将会等待 所有的ConnetionRunner 结束后才能继续执行    static CountDownLatch end;    public static void main(String[] args) throws Exception{        //通过修改线程数据量,观察数据变化        int threadCount=10;        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 ConnetionRunner(count,got,notGot),"ConnectionRunnerThread");            thread.start();        }        start.countDown();        end.await();        System.out.println("total invoke:"+(threadCount*count));        System.out.println("got connection:"+got);        System.out.println("not got connection:"+notGot);    }    static class ConnetionRunner implements Runnable{        int count;        AtomicInteger got;        AtomicInteger notGot;        public ConnetionRunner(int count,AtomicInteger got,AtomicInteger notGot){            this.count=count;            this.got=got;            this.notGot=notGot;        }        public void run() {            try {                start.await();            } catch (InterruptedException e) {                e.printStackTrace();            }            while (count>0) {                try {                    Connection connection=(Connection) pool.fetchConnection(1000);                    if(connection!=null){                        try {                            //从线程池中获取连接,如果1000ms内无法获取到,将返回null                            //分别统计连接获取的数量got 和未获取到的数量notGot                            connection.createStatement();                            connection.commit();                        } finally {                            pool.releaseConnection(connection);                            got.incrementAndGet();                        }                    }else{                        notGot.incrementAndGet();                    }                } catch (Exception e) {                }finally{                    count--;                }            }            end.countDown();        }    }}
原创粉丝点击