java多线程之-自定义数据库连接池
1. 背景
数据库链接池大家不陌生吧...
不多说了, 直上代码...
2. 连接池具体实现
1.jdbc 链接的实例对象
/** * @author 姿势帝 - 博客园 * @address https://www.cnblogs.com/newAndHui/ * @WeChat 851298348 * @create 02/19 8:17 * @description * <p> * 模拟一个实现 jdbc 链接的实例 * </p> */ @Data public class MyConnectionImpl implements Connection { private String name; // TODO 实现接口的方法 }
2. 连接池对象
package com.ldp.demo09Pool;import lombok.extern.slf4j.Slf4j;
import java.sql.Connection;
import java.util.concurrent.atomic.AtomicIntegerArray;/**
@author 姿势帝 - 博客园
@address https://www.cnblogs.com/newAndHui/
@WeChat 851298348
@create 02/19 8:10
@description <p>
自定义一个数据库连接池
练习多线程, 原子性等概念的理解
</p>
*/
@Slf4j
public class MyDataPool {
// 1. 链接数
private int poolSize;
// 2. 链接对象数组
private Connection[] connectionArray;
// 3. 记录链接状态的数组,0- 链接可用,1- 链接不可用
private AtomicIntegerArray statusArray;/**
- 构造方法
- @param poolSize
*/
public MyDataPool(int poolSize) {
this.poolSize = poolSize;
this.connectionArray = new Connection[poolSize];
this.statusArray = new AtomicIntegerArray(new int[poolSize]);
for (int i = 0; i < poolSize; i++) {
connectionArray[i] = new MyConnectionImpl("连接对象 -" + i);
}
}/**
- 获取一个链接
- @return
*/
public Connection getConnection() {
while (true) {
for (int i = 0; i < poolSize; i++) {
if (statusArray.get(i) == 0) {
// 0- 链接可用,1- 链接不可用
if (statusArray.compareAndSet(i, 0, 1)) {
// 获取连接成功
return connectionArray[i];
}
}
}
synchronized (this) {
try {
// 如果没获取到链接, 等待, 实际开发中这里可以设置一个等待时长
log.info("无可用链接等待中....");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}/**
- 将连接放回连接池
- @param connection
*/
public void closeConnection(Connection connection) {
for (int i = 0; i < poolSize; i++) {
if (connectionArray[i] == connection) {
// 设置归返的链接可用
statusArray.set(i, 0);
// 唤醒其他线程获取连接
synchronized (this) {
this.notify();
}
break;
}
}
// 异常处理...
}
}
3. 测试
package com.ldp.demo09Pool;import com.common.MyThreadUtil;
import lombok.extern.slf4j.Slf4j;import java.sql.Connection;
import java.util.Random;/**
- @author 姿势帝 - 博客园
- @address https://www.cnblogs.com/newAndHui/
- @WeChat 851298348
- @create 02/19 8:42
- @description
*/
@Slf4j
public class Test01 {
/**
- 测试连接池使用
- @param args
*/
public static void main(String[] args) {
MyDataPool dataPool = new MyDataPool(3);
for (int i = 0; i < 10; i++) {
new Thread(() -> {
Connection connection = dataPool.getConnection();
log.info("获得链接对象:{}", connection);
// 模拟使用时间
MyThreadUtil.sleep(new Random().nextInt(5));
// 归返链接
dataPool.closeConnection(connection);
log.info("链接已归还");
}, "service-" + i).start();
}
}
}