package com.example.demo.hmjuc.day17;
import com.example.demo.hmjuc.Sleep;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.atomic.AtomicIntegerArray;
/**
* @author zhangqi
* @date 2022/6/4 21:30
*/
public class TestPool {
public static void main(String[] args) {
Pool pool = new Pool(2);
for (int i = 0; i < 5; i++) {
new Thread(() -> {
Connection borrow = pool.borrow();
Sleep.sleep(new Random().nextInt(1000));
pool.free(borrow);
}).start();
}
}
}
/**
* 自定义的线程池
*/
class Pool {
/**
* 链接池大小 简单实现 不可改变
*/
private final Integer poolSize;
/**
* 链接数组 数据库数据库链接
*/
private Connection[] connections;
/**
* 链接状态 0: 空闲 1:使用
*/
private AtomicIntegerArray statusArray;
/**
* 构造数据库链接池
*
* @param poolSize 初始线程池的大小
*/
public Pool(Integer poolSize) {
this.poolSize = poolSize;
this.connections = new Connection[poolSize];
this.statusArray = new AtomicIntegerArray(poolSize);
for (int i = 0; i < poolSize; i++) {
connections[i] = createConnection();
}
}
/**
* 使用链接
*
* @return 链接池中的链接
*/
public Connection borrow() {
while (true) {
for (int i = 0; i < poolSize; i++) {
if (statusArray.get(i) == 0 && statusArray.compareAndSet(i, 0, 1)) {
return connections[i];
}
}
// 没有可用链接等待
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 归还链接
*
* @param conn 链接
*/
public void free(Connection conn) {
for (int i = 0; i < poolSize; i++) {
if (connections[i] == conn) {
statusArray.set(i, 0);
synchronized (this) {
this.notify();
}
break;
}
}
}
/**
* 创建数据库链接
*
* @return 数据库链接
*/
private Connection createConnection() {
// 获取数据库驱动
Connection conn = null;
Properties props = new Properties();
try {
Class.forName("com.mysql.cj.jdbc.Driver");
DriverManager.setLoginTimeout(10);
props.setProperty("user", "root");
props.setProperty("password", "root");
// 设置可以获取remarks信息
props.setProperty("remarks", "true");
// 设置可以获取tables remarks信息(mysql时必须设置)
props.setProperty("useInformationSchema", "true");
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/delivery?serverTimezone=GMT%2B8&useSSL=false&useOldAliasMetadataBehavior=true&useUnicode=true&characterEncoding=utf8", props);
conn.setAutoCommit(true);
} catch (Exception e) {
e.printStackTrace();
close(conn);
}
return conn;
}
/**
* 关闭数据库对象
*
* @param obj 数据库对象
*/
private static void close(Object obj) {
if (obj == null) {
return;
}
if (obj instanceof ResultSet) {
try {
((ResultSet) obj).close();
} catch (SQLException e) {
e.printStackTrace();
}
} else if (obj instanceof Statement) {
try {
((Statement) obj).close();
} catch (SQLException e) {
e.printStackTrace();
}
} else if (obj instanceof Connection) {
Connection c = (Connection) obj;
try {
if (!c.isClosed()) {
c.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
06-01
583
07-27
1165