zoukankan      html  css  js  c++  java
  • 《四 数据库连接池源码》手写数据库连接池

    读取外部配置信息

    //外部配置文件信息
    public class DbBean {
    
        /* 链接属性 */
        private String driverName = "com.mysql.jdbc.Driver";
    
        private String url = "jdbc:mysql://localhost:3306/test";
    
        private String userName = "root";
    
        private String password = "root";
    
        private String poolName = "thread01";// 连接池名字
    
        private int minConnections = 1; // 空闲池,最小连接数
    
        private int maxConnections = 10; // 空闲池,最大连接数
    
        private int initConnections = 5;// 初始化连接数
    
        private long connTimeOut = 1000;// 重复获得连接的频率
    
        private int maxActiveConnections = 100;// 最大允许的连接数,和数据库对应
    
        private long connectionTimeOut = 1000 * 60 * 20;// 连接超时时间,默认20分钟
    
        public String getDriverName() {
            return driverName;
        }
    
        public void setDriverName(String driverName) {
            this.driverName = driverName;
        }
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getPoolName() {
            return poolName;
        }
    
        public void setPoolName(String poolName) {
            this.poolName = poolName;
        }
    
        public int getMinConnections() {
            return minConnections;
        }
    
        public void setMinConnections(int minConnections) {
            this.minConnections = minConnections;
        }
    
        public int getMaxConnections() {
            return maxConnections;
        }
    
        public void setMaxConnections(int maxConnections) {
            this.maxConnections = maxConnections;
        }
    
        public int getInitConnections() {
            return initConnections;
        }
    
        public void setInitConnections(int initConnections) {
            this.initConnections = initConnections;
        }
    
        public long getConnTimeOut() {
            return connTimeOut;
        }
    
        public void setConnTimeOut(long connTimeOut) {
            this.connTimeOut = connTimeOut;
        }
    
        public int getMaxActiveConnections() {
            return maxActiveConnections;
        }
    
        public void setMaxActiveConnections(int maxActiveConnections) {
            this.maxActiveConnections = maxActiveConnections;
        }
    
        public long getConnectionTimeOut() {
            return connectionTimeOut;
        }
    
        public void setConnectionTimeOut(long connectionTimeOut) {
            this.connectionTimeOut = connectionTimeOut;
        }
    
    }

    创建数据库连接池

    /**
     * 数据库连接池<br>
     * 
     * 1.初始化<br>
     * ####线程池核心容器 空闲线程数、活动线程数<br>
     * ###构造函数 1.1.1初始化线程,存放在空闲线程池中<br>
     * 2.获取连接 <br>
     * ####1.判断存在线程数是否大于最大线程 如果大于最大线程数,则进行等待...<br>
     * ####2.判断空闲线程数是否大于0 如果空闲线程数<0,创建新的连接<br>
     * ####3.如果空闲线程数>0,则获取当前空闲线程,存入在活动线程集合中 <br>
     * 3.释放连接 <br>
     * ####3.1.1.判断空闲线程数是否大于最大线程数 <br>
     * ####3.1.2.如果空闲线程数小于最大线程数,将该连接收回到 空闲 线程集合中<br>
     * ####3.1.3.删除该连接对应的活动线程集合数据<br>
     * <br>
     * 
     * 
     * 作者: 每特教育-余胜军<br>
     * 联系方式:QQ644064779|WWW.itmayiedu.com<br>
     */
    public class ConnectionPool implements IConnectionPool {
    
        // 空闲线程集合
        private List<Connection> freeConnection = new Vector<Connection>();
        // 活动线程集合
        private List<Connection> activeConnection = new Vector<Connection>();
        // 记录线程总数
        private static int connCount = 0;
        private DbBean dbBean;
    
        public ConnectionPool(DbBean dbBean) {
            this.dbBean = dbBean;
            init();
        }
    
        public void init() {
            try {
    
                for (int i = 0; i < dbBean.getInitConnections(); i++) {
                    Connection newConnection = newConnection();
                    if (newConnection != null) {
                        // 添加到空闲线程中...
                        freeConnection.add(newConnection);
                    }
                }
    
            } catch (Exception e) {
    
            }
        }
    
        // 创建新的Connection
        private Connection newConnection() {
            try {
                if (dbBean == null) {
                    return null;
                }
                Class.forName(dbBean.getDriverName());
                Connection connection = DriverManager.getConnection(dbBean.getUrl(), dbBean.getUserName(),
                        dbBean.getPassword());
                connCount++;
                return connection;
            } catch (Exception e) {
                return null;
            }
    
        }
    
        public Connection getConnection() {
            // * ####1.判断活动线程数是否大于最大线程 如果大于最大线程数,则进行等待...<br>
            Connection connection = null;
            try {
    
                if (connCount < dbBean.getMaxActiveConnections()) {
                    // 还有活动线程可以使用
                    // * ####2.判断空闲线程数是否大于0 如果空闲线程数<0,创建新的连接<br>
                    if (freeConnection.size() > 0) {
                        connection = freeConnection.remove(0);// 等于freeConnection.get(0);freeConnection.remove(0);
                    } else {
                        // 创建新的连接
                        connection = newConnection();
                    }
    
                    boolean available = isAvailable(connection);
                    if (available) {
                        activeConnection.add(connection);
                    } else {
                        connCount--;// i--操作
                        connection = getConnection();// 递归调用getConnection方法
                    }
                } else {
                    // 大于最大线程数,进行等待,重新获取连接
                    wait(dbBean.getConnTimeOut());
                    connection = getConnection();// 递归调用getConnection方法
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            // * ####3.如果空闲线程数>0,则获取当前空闲线程,存入在活动线程集合中 <br>
            return connection;
        }
    
        // 判断连接是否可用
        public boolean isAvailable(Connection connection) {
            try {
                if (connection == null || connection.isClosed()) {
                    return false;
                }
    
            } catch (Exception e) {
                // TODO: handle exception
            }
            return true;
    
        }
    
        public void releaseConnection(Connection connection) {
            try {
                if (connection == null) {
                    return;
                }
                if (isAvailable(connection)) {
                    // 判断空闲线程数是否大于最大线程数
                    if (freeConnection.size() < dbBean.getMaxConnections()) {
                        freeConnection.add(connection);
                    } else {
                        // 空闲线程数已经满了
                        connection.close();
                    }
                    activeConnection.remove(connection);
                    connCount--;
                    notifyAll();
    
                }
    
            } catch (Exception e) {
    
            }
    
        }
    
    }

    测试运行结果

    public class Test001 {
    
        public static void main(String[] args) {
    
            DBThread dBThread = new DBThread();
            for (int i = 1; i <= 3; i++) {
                Thread thread = new Thread(dBThread, "用户线程" + i);
                thread.start();
            }
    
        }
    
    }
    
    class DBThread implements Runnable {
    
        public void run() {
            for (int i = 0; i < 10; i++) {
                Connection connection = ConnectionPoolManager.getConnection();
                System.out.println(Thread.currentThread().getName() + ",connection:" + connection);
                ConnectionPoolManager.releaseConnection(connection);
            }
        }
    
    }
  • 相关阅读:
    python学习笔记之--read、readline和readlines
    目录操作习题
    递归习题
    文件操作练习题
    HandleBase句柄的5种写法
    ContextBase
    BasegoSort
    PrototypePra原型_设计订单保存
    DesignPattenTemplate模板模式
    DesignPattenStrategy策略模式
  • 原文地址:https://www.cnblogs.com/a1304908180/p/10639759.html
Copyright © 2011-2022 走看看