造轮子之数据库连接池

原创
2016/04/29 10:59
阅读数 73

线程池谈谈我自己的理解吧:

  1. 先创建固定数量的连接,之后放在一个容器中
  2. 使用时从容器中拿
  3. 容器中的连接数量少于等于0,所有获取连接的动作等待;
  4. 容器中的连接数量大于0,则获取连接,在连接用完之后就返回到容器中

针对以上的理解,在编程中可以这样实现:

  • 创建固定连接,放在 LinkedList<Connection> 中,选择这个是链表操作添加删除效率高
  • 当 LinkedList.size() <= 0, 则该动作执行 wait() 操作
  • 当 LinkedList.size() > 0, 获取连接 Connection con 交付获取者使用
  • 当使用者使用完 con 后,调用 close() 时, 这时候将 con 添加到 LinkedList<Connection> 中,这个是编程难点
  • 针对编程难点,我有2种解决方案
  1. 使用代理,在用户获取con时,我们返回的是代理后的con,这样,当客户使用con的close时,实际是执行LiskedList.add() 方法
  2. 规定使用者使用特定的close(Connection con) 方法;该方法简单,我就不实现了

下面是主要实现代码

public Connection getConnection() throws SQLException {
        synchronized(MysqlUtils.class) {
            while(list.size() <= 0 ) {
                try {
                    log.info(Thread.currentThread().getName() + " wait() " );
                    MysqlUtils.class.wait();
                } catch (InterruptedException e) {
                    log.error(" Thread " + Thread.currentThread().getName()
                            + "  wait() error!");
                }
            }
        
        final Connection con = list.removeFirst();
        Connection conn =  (Connection) Proxy.newProxyInstance(MysqlUtils.class.getClassLoader()
            , new Class[]{Connection.class}
            ,new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if(!method.getName().equals("close")) {
                    return method.invoke(con, args);
                } else {
                    synchronized(MysqlUtils.class) {
                        list.add(con);
                        MysqlUtils.class.notifyAll();
                        log.info(Thread.currentThread().getName() + " release connection ");
                        return null;
                    }
                }
            }
        });
        
        return conn;
    
        }
    }




池子的最大连接,最少连接,定时之类的很多都没有实现,只是简单的弄了一个固定连接数量

本篇博客参考了http://www.cnblogs.com/xdp-gacl/p/4002804.html 博客的代码,特此指出,也算是我自己的总结

以上有什么错误的地方,欢迎大家指出,目前也在学习中,一起进步哈


12楼:frankiegao123 发表于 2012-01-21 13:14 回复此评论 一个可以用于生产环境中的连接池最少需要具备以下条件: 1:实现了 javax.sql.DataSource 接口 2:从连接池中获得的连接,在调用 Connection#close 时并不是真正意义上的关闭连接,而是将其还回到池中去 3:池中的连接被数据库服务端关闭时,这些连接该如何处理 4:连接回收问题。如果设了最大 50 个连接,在并发量高时正好用到这 50 个连接,如果高并发期过后,假如只有 10 个连接被用到,那剩下的 40 个应该要被回收,不能占用这些宝贵的资源 5:如果网络中断后又重新连接上,池中的连接该如何处理,这与 3 是类似的,涉及一个池中连接的健康检查机制


展开阅读全文
打赏
1
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
1
分享
返回顶部
顶部