zoukankan      html  css  js  c++  java
  • 手写数据库连接池

    几个概念:
    1、初始化连接数,比如存在5个Connection
    2、最大连接数,比如最大10个Connection
    3、空闲池,存放当钱没有被使用的connection
    4、活动池,存放当前正在使用的connection
    5、执行完业务逻辑后,进行连接的释放,即放入空闲池
    6、数据库本身也对连接数有一定的限制,比如MySql同时允许最大连接100个

    初始化时生成的默认连接数放置在空闲连接池中。
    容器必须是线程安全的,并发操作连接对象。(从空闲池到活动池)


    注意几个点:
    当connection使用完成之后,需要重新放置到空闲池里面。
    空闲池和活动池必须是线程安全的
    获取连接时,当检测到活动池中的connection数量已经超过最大连接数,则进行重新获取(递归调用)。

    从空闲连接池中获取连接实例后,需要把该实例添加至活动空闲池中,同时删除空闲池中的记录


    配置类:手动添加一下setter和getter方法

    package pool;
    /**
     * Created by 156 on 2019/3/28.
     *
     * 需要 MySql-connect 5.x版本
     */
    public class DbBean {
    
        /* 链接属性 */
        private String driverName = "com.mysql.jdbc.Driver";
        private String url = "jdbc:mysql://localhost:3306/spring5";
        private String userName = "root"
        private String password = "123456";
        private int minConnections = 1; // 空闲池,最小连接
        private int maxConnections = 10; // 空闲池,最大连接数
        private int initConnections = 5;// 初始化连接数
    }

    连接池

        package pool;
        
        import java.sql.Connection;
        import java.sql.DriverManager;
        import java.util.List;
        import java.util.Vector;
        
        /**
         * Created by 156 on 2019/3/28.
         */
        public class ConnectionPool implements IConnectionPool
        {
        
            public void setFreeConnection(List<Connection> freeConnection) {
                this.freeConnection = freeConnection;
            }
        
            // 空闲线程集合
            private List<Connection> freeConnection = new Vector<Connection>();
        
            // 活动线程集合
            private List<Connection> activeConnection = new Vector<Connection>();
        
        
            private DbBean dbBean;
        
            public ConnectionPool(DbBean dbBean) throws Exception
            {
                this.dbBean = dbBean;
                init();
            }
        
            public void init() throws Exception
            {
                //  根据初始化的连接数,进行创建Connection实例
                for (int i = 0; i < dbBean.getInitConnections(); i++)
                {
                    Connection instance = createConn();
                    if (null != instance )
                    {
                        freeConnection.add(instance); //  将创建的实例添加至空闲池中
                    }
                }
            }
            // 创建新的Connection
            private Connection createConn()
            {
                try
                {
                    if (null == dbBean)
                    {
                        return null;
                    }
                    Class.forName(dbBean.getDriverName());
                    Connection connection = DriverManager.getConnection(dbBean.getUrl(), dbBean.getUserName(),
                            dbBean.getPassword());
                    return connection;
                } catch (Exception e) {
                    return null;
                }
        
            }
        
            /***
             * 获取connecton
             * 1、首先判断空闲池中是否还有connection实例
             * 2、当空闲池线中没有connection实例时,
             *      判断当前活动线程池中存在的connection数目是否大于最大connection数目
             *
             *
             * @return
             */
            public Connection getConnection()
            {
                Connection connection = null;
        
                //  说明空闲池中还有未使用的connection实例,直接返回
                //  不需要记录该connectio获取的动作
                if (freeConnection.size()>0)
                {
                    //  1、备份需要返回的connection
                    Connection reConn = freeConnection.get(0);
                    //  判断当前连接是否可用
                    if(!isAvailable(reConn)){
                        return null;
                    }
                    // 2、从空闲连接池中移除
                    freeConnection.remove(0);
                    // 3、添加至活动连接池中
                    activeConnection.add(reConn);
                    return reConn; //  返回一个connection实例
                }
                // 当前活动connection实例数目小于配置的最大数目时,进行新实例的创建
                //  在返回一个Connection实例的同时,同时记录一下新生成的connection
                if ( activeConnection.size()<dbBean.getMaxConnections())
                {
                    // 1、重新生成连接
                    Connection newC = createConn();
                    //  判断当前连接是否可用
                    if(!isAvailable(newC)){
                        return null;
                    }
                    // 2、记录一下新生成的connection
                    activeConnection.add(newC);
                    return createConn();
                }
                // 当前活动的connection实例已经大于最大数目,则进行重新获取
                if(activeConnection.size()>dbBean.getMaxConnections())
                {
                   return getConnection();
                }
        
                return null;
            }
        
            public void releaseConnection(Connection connection)
            {
                try
                {
                    if (connection == null)
                    {
                        return;
                    }
                    if (isAvailable(connection))
                    {
                        // 判断空闲线程数是否大于最大线程数
                        if (freeConnection.size() < dbBean.getMaxConnections())
                        {
                            freeConnection.add(connection);
                        }
                    }
        
                } catch (Exception e) {
        
                }
            }
        
            // 判断连接是否可用
            public boolean isAvailable(Connection connection) {
                try {
                    if (connection == null || connection.isClosed()) {
                        return false;
                    }
        
                } catch (Exception e) {
                    // TODO: handle exception
                }
                return true;
        
            }
        
        }

    测试

     @Test
        public void test() throws Exception {
    
            ConnectionPool connectionPool = new ConnectionPool(new DbBean());
    
            for (int i=1;i<=11;i++){
    
                System.out.println(i+"===>"+connectionPool.getConnection());
    
            }
        }
  • 相关阅读:
    将Word,PDF文档转化为图片
    图像识别
    ckeditor_4.5.10_full,ckfinder_aspnet_2.6.2,插件使用
    检索COML类工厂中 CLSID为 {00024500-0000-0000-C000-000000000046}的组件时失败,原因是出现以下错误: 80070005" 《终结篇》
    wireshark抓包图解 TCP三次握手/四次挥手详解
    经常开发出现bug的同事,
    简单理解Socket
    eclipse下如何配置tomcat
    Windows 7系统安装MySQL5.5.21图解
    Tomcat7.0.22在Windows下详细配置过程
  • 原文地址:https://www.cnblogs.com/nevegiveup/p/12287069.html
Copyright © 2011-2022 走看看