代码已上传到GitHub,有兴趣的同学可以下载来看看:https://github.com/ylw-github/Java-CodeAnalysis-Demo
先看看包结构:
1.添加maven依赖:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.25</version> </dependency>
2.配置文件DbBean:
package com.ylw.db_pool; 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 = "123456"; 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; } }
3.定义连接池接口并实现:
// 1.定义数据库连接池接口: public interface IConnectionPool { // 获取连接(重复利用机制) public Connection getConnection(); // 释放连接(可回收机制) public void releaseConnection(Connection connection); } //2.实现数据库连接池接口: public class ConnectionPool implements IConnectionPool { // 使用线程安全的集合 空闲线程 容器 没有被使用的连接存放 private List<Connection> freeConnection = new Vector<Connection>(); // 使用线程安全的集合 活动线程 容器 容器正在使用的连接 private List<Connection> activeConnection = new Vector<Connection>(); private DbBean dbBean; private int countConne = 0; public ConnectionPool(DbBean dbBean) { // 获取配置文件信息 this.dbBean = dbBean; init(); } // 初始化线程池(初始化空闲线程) private void init() { if (dbBean == null) { return;// 注意最好抛出异常 } // 1.获取初始化连接数 for (int i = 0; i < dbBean.getInitConnections(); i++) { // 2.创建Connection连接 Connection newConnection = newConnection(); if (newConnection != null) { // 3.存放在freeConnection集合 freeConnection.add(newConnection); } } } // 创建Connection连接 private synchronized Connection newConnection() { try { Class.forName(dbBean.getDriverName()); Connection connection = DriverManager.getConnection(dbBean.getUrl(), dbBean.getUserName(), dbBean.getPassword()); countConne++; return connection; } catch (Exception e) { return null; } } // 调用getConnection方法 --- 获取连接 public synchronized Connection getConnection() { try { Connection connection = null; // 思考:怎么知道当前创建的连接>最大连接数 if (countConne < dbBean.getMaxActiveConnections()) { // 小于最大活动连接数 // 1.判断空闲线程是否有数据 if (freeConnection.size() > 0) { // 空闲线程有存在连接 // ==freeConnection.get(0);freeConnection.remove(0) // 拿到在删除 connection = freeConnection.remove(0); } else { // 创建新的连接 connection = newConnection(); } // 判断连接是否可用 boolean available = isAvailable(connection); if (available) { // 存放在活动线程池 activeConnection.add(connection); countConne++; } else { countConne--; connection = getConnection();// 怎么使用重试? 递归算法 } } else { // 大于最大活动连接数,进行等待 wait(dbBean.getConnTimeOut()); // 重试 connection = getConnection(); } return connection; } catch (Exception e) { return null; } } // 判断连接是否可用 public boolean isAvailable(Connection connection) { try { if (connection == null || connection.isClosed()) { return false; } } catch (Exception e) { // TODO: handle exception } return true; } // 释放连接 回收 public synchronized void releaseConnection(Connection connection) { try { // 1.判断连接是否可用 if (isAvailable(connection)) { // 2.判断空闲线程是否已满 if (freeConnection.size() < dbBean.getMaxConnections()) { // 空闲线程没有满 freeConnection.add(connection);// 回收连接 } else { // 空闲线程已经满 connection.close(); } activeConnection.remove(connection); countConne--; notifyAll(); } } catch (Exception e) { // TODO: handle exception } } }
4.数据库连接池管理者:
// 管理线程池 public class ConnectionPoolManager { private static DbBean dbBean = new DbBean(); private static ConnectionPool connectionPool = new ConnectionPool(dbBean); // 获取连接(重复利用机制) public static Connection getConnection() { return connectionPool.getConnection(); } // 释放连接(可回收机制) public static void releaseConnection(Connection connection) { connectionPool.releaseConnection(connection); } }
好的,以上数据库连接池代码编写完成,接下来进行单元测试:
public class DBPoolTest { @Test public void test() { ThreadConnection dBThread = new ThreadConnection(); for (int i = 1; i <= 3; i++) { Thread thread = new Thread(dBThread, "用户线程" + i); thread.start(); } } class ThreadConnection 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); } } } }
总结: