自定义实现jdbc数据库连接池
连接池作用
- 达到资源的复用
- 提高响应速度(不必要的连接与关闭)
- 资源的分配策略,可以统一管理
连接池的大致实现思路
- 核心参数:
空闲连接数: 没有使用的连接数
活动连接数: 正在使用的连接数
最大连接数: 最多允许存在的连接数 - 初始化连接池(用容器封装:比如Vecotr sql包下)
- 实现获取Connection的方法:
(1) 判断当前连接数(countPool) 是否小于 最大连接数
如果当前连接数 小于最大连接数
则 判断空闲连接池中是否有连接可用, 有则直接使用 (可判断当前获取的连接是否存活)
否则: 创建一个连接进行使用
(2)当前连接数大于了 最大连接数
则放入执行线程的任务进行等待 - 释放连接,回收连接数机制
(1) 判断当前空闲连接池 中的连接数是否小于 最大空闲连接数
若小于, 则存放于空闲连接池
否则: 直接关闭改连接
1.定义 连接池接口
2. 简易的封装一个连接池各个参数的Bean(可通过配置文件获取)
3. 实现数据库连接池
4. 封装连接池,对外提供访问
5. 测试
6. 结果
有重复利用数据库连接
7.核心类代码
/**
* 实现思路:
* 关键参数: 空闲连接 , 活动连接, 最大连接
* 1. 初始化连接, 连接安全问题 Vector<Connection>
* 2. 实现获取连接的方法
* 3. 回收连接机制(回收资源)
* @author xzb
*
*/
public class ConnectionPool implements IConnectionPool {
/**存放空闲连接数*/
private static List<Connection> freePool = new Vector<Connection>();
/**当前正在运行的连接数*/
private static List<Connection> activePool = new Vector<Connection>();
/**
* 记录当前线连接总数
*/
private static AtomicInteger countPool = new AtomicInteger();
/**队列存放任务*/
private static BlockingQueue<Connection> linkedBlockingQueue = new LinkedBlockingQueue<Connection>();
/**读取配置文件*/
private DbBean dbBean;
public ConnectionPool(DbBean dbBean) {
try {
this.dbBean = dbBean;
initPool();
} catch (Exception e) {
}
}
/**
* 初始化连接
*/
private void initPool() throws Exception {
if (this.dbBean == null) {
throw new Exception("连接");
}
for (int i = 0; i < this.dbBean.getInitConnections(); i++) {
// 创建连接
Connection connection = createConnection();
freePool.add(connection);
}
}
/**
* 创建数据库连接
* @throws SQLException
* @throws ClassNotFoundException
*/
private Connection createConnection() {
try {
Class.forName(this.dbBean.getDriverName());
Connection connection = DriverManager.getConnection(this.dbBean.getUrl(), this.dbBean.getUserName(), this.dbBean.getPassword());
countPool.incrementAndGet();
return connection;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取连接
*/
public synchronized Connection getConnection() {
Connection connection = null;
try {
// 当前连接数小于 最大允许的线程数
if (countPool.get() < this.dbBean.getMaxActiveConnections()) {
// 判断空闲连接池是否还有
if (freePool.size() > 0 ) {
// 有,则直接从空闲池中获取
connection = freePool.remove(0);
}else {
// 创建
connection = createConnection();
}
// 判断当前线程是否可用
if (!isAccessable(connection)) {
// 当前连接都没有存活,则创建一个返回
if (countPool.get() <= 0) {
connection = createConnection();
}
// 当前空闲数-1
countPool.decrementAndGet();
getConnection();
} else {
activePool.add(connection);
// countPool.incrementAndGet();
}
} else {
// 当前没有可用连接,存入队列,等待
this.wait(dbBean.getConnTimeOut());
// 重试
getConnection();
}
} catch (Exception e) {
e.printStackTrace();
}
return connection;
}
/**
* 判断当前连接是否存活
*/
private boolean isAccessable(Connection connection) throws SQLException {
if (connection == null || connection.isClosed()) {
return false;
}
return true;
}
/**
* 连接回收机制
*/
public synchronized Boolean reselveConnection(Connection connection) {
try {
if (isAccessable(connection)) {
// 可用, 判断是否放回空闲线程池中
if (freePool.size() < this.dbBean.getMaxConnections()) {
// 空闲线程池 小于最大空闲线程池容量, 则回收
freePool.add(connection);
} else {
countPool.decrementAndGet();
connection.close();
}
// 正在运行的连接移除
activePool.remove(connection);
// 唤醒
this.notifyAll();
} else {
// 不可用,直接关闭
if (connection != null ) {
countPool.decrementAndGet();
connection.close();
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}