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);
            }
        }
    
    }
  • 相关阅读:
    mySQL优化方案
    java之自动过滤提交文本中的html代码script代码
    java小技术之生成二维码
    微信扫码支付功能详细教程————Java
    java实现发送邮件服务器,SMTP协议发送邮件
    『重构--改善既有代码的设计』读书笔记----序
    Linux导航神器-----autojump
    绘图时,根据size()和自定义rect编程的区别
    Qt中如何在QCursor移动的时候不触发moveEvent
    Qt远程机开发时光标注意问题
  • 原文地址:https://www.cnblogs.com/a1304908180/p/10639759.html
Copyright © 2011-2022 走看看