另一版本请查看本人博客:《黑马JUC—自定义连接池:享元模式+AtomicIntegerArray+Semaphore》
一个线上商城应用,QPS 达到数千,如果每次都重新创建和关闭数据库连接,性能会受到极大影响。 这时 预先创建好一批连接,放入连接池。一次请求到达后,从连接池获取连接,使用完毕后再还回连接池,这样既节约 了连接的创建和关闭时间,也实现了连接的重用,不至于让庞大的连接数压垮数据库。
实现
连接池
@Slf4j(topic = "c.seven-Demo1")
class ConnectionPool{
//1.连接池大小
private final int size;
//2.连接对象数组
private Connection[] connections;
//3.连接状态数组 0:空闲 1:忙碌
private AtomicIntegerArray status;
//4.构造器初始化
ConnectionPool(int size) {
this.size=size;
connections = new Connection[size];
status=new AtomicIntegerArray(new int[size]);
for (int i = 0; i < size; i++) {
connections[i]=new DiyConnection();
}
}
//5.借连接
public Connection borrow(){
while (true){
//成功,获取空闲连接
for (int i = 0; i < size; i++) {
if(status.get(i)==0){
if (status.compareAndSet(i,0,1)) {
log.debug("获得连接"+i);
return connections[i];
}
}
}
//失败,没有空闲连接。进入阻塞队列
synchronized (this){
try {
log.debug("获取失败");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//6.还连接
public void fee(Connection connection){
for (int i = 0; i < size; i++) {
if(connections[i]==connection){
log.debug("释放连接"+i);
status.set(i,0);
synchronized (this){
this.notifyAll();
}
break;
}
}
}
}
连接对象
class DiyConnection implements Connection{
//略
}
测试
代码
public static void main(String[] args) {
//1.创建连接池实例
ConnectionPool pool = new ConnectionPool(2);
//2.创建 5 个线程借连接
for (int i = 0; i < 5; i++) {
new Thread(() -> {
//2.1 借连接
Connection conn = pool.borrow();
try {
//2.2 模拟连接使用
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//2.3 释放连接
pool.fee(conn);
}).start();
}
}
结果
19:51:57 [Thread-0] c.seven-Demo1 - 获得连接0
19:51:57 [Thread-1] c.seven-Demo1 - 获得连接1
19:51:57 [Thread-2] c.seven-Demo1 - 获取失败
19:51:57 [Thread-3] c.seven-Demo1 - 获取失败
19:51:57 [Thread-4] c.seven-Demo1 - 获取失败
19:51:58 [Thread-1] c.seven-Demo1 - 释放连接1
19:51:58 [Thread-0] c.seven-Demo1 - 释放连接0
19:51:58 [Thread-4] c.seven-Demo1 - 获得连接0
19:51:58 [Thread-2] c.seven-Demo1 - 获取失败
19:51:58 [Thread-3] c.seven-Demo1 - 获得连接1
19:51:59 [Thread-4] c.seven-Demo1 - 释放连接0
19:51:59 [Thread-3] c.seven-Demo1 - 释放连接1
19:51:59 [Thread-2] c.seven-Demo1 - 获得连接0
19:52:00 [Thread-2] c.seven-Demo1 - 释放连接0