1、自定义连接类
public class MyConnection implements InvocationHandler {
//连接
private Connection relConnection;
//数据源
private MyDataSource dataSource;
public MyConnection(MyDataSource dataSource){
this.dataSource = dataSource;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("close")){
this.dataSource.pushConnection(this);
return null;
}
return method.invoke(this.relConnection,args);
}
public Connection getRelConnection() {
return relConnection;
}
public void setRelConnection(Connection relConnection) {
this.relConnection = relConnection;
}
}
2、自定义数据源类
public class MyDataSource implements DataSource {
//驱动类
private String driver;
//数据库地址
private String url;
//用户名
private String userId;
//密码
private String password;
//是否自动提交
private boolean autoCommit = true;
//连接池
private final LinkedList<MyConnection> connectionPool = new LinkedList<>();
//当前连接总数
private int nowSize = 0;
private int activeSize = 0;
//最大连接数
private int maxSize = 10;
//最小连接数
private int minSize = 1;
//等待获取连接时间
private long waitTime = 10000;
public MyDataSource(String driver,String url,String userId,String password){
this.driver = driver;
this.url = url;
this.userId = userId;
this.password = password;
}
/**
* 获取连接
* @return 连接
*/
public MyConnection popConnection() throws InterruptedException, SQLException {
synchronized (this.connectionPool){
long waitNow = System.currentTimeMillis();
long waitOver = waitNow + this.waitTime;
while(this.connectionPool.isEmpty()){
if(this.nowSize < this.maxSize-1){
MyConnection connection = buildMyConnection();
this.nowSize++;
this.activeSize++;
return connection;
}
if(this.waitTime >0 ){
System.out.println("无闲置的连接,等待中……");
this.connectionPool.wait(waitTime);
}
waitTime = waitOver - System.currentTimeMillis();
}
this.activeSize++;
out.println("闲置总数:"+connectionPool.size()+", 活跃总数:"+this.activeSize);
return this.connectionPool.removeFirst();
}
}
private MyConnection buildMyConnection() throws SQLException {
MyConnection conn = new MyConnection(this);
conn.setRelConnection(getConnection());
return conn;
}
public void pushConnection(MyConnection connection) throws SQLException {
synchronized (this.connectionPool){
if(this.connectionPool.size()>maxSize){
connection.getRelConnection().close();
this.activeSize--;
}
this.connectionPool.addLast(connection);
this.activeSize--;
this.connectionPool.notifyAll();
}
}
@Override
public Connection getConnection() throws SQLException {
try {
Class.forName(this.driver);
Connection connection = DriverManager.getConnection(this.url,this.userId,this.password);
connection.setAutoCommit(this.autoCommit);
return connection;
} catch (ClassNotFoundException e) {
throw new RuntimeException("get connection fail because "+e.getMessage());
}
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
public boolean isAutoCommit() {
return autoCommit;
}
public void setAutoCommit(boolean autoCommit) {
this.autoCommit = autoCommit;
}
public void setWaitTime(long waitTime) {
this.waitTime = waitTime;
}
public void setMaxSize(int maxSize) {
this.maxSize = maxSize;
}
public void setMinSize(int minSize) {
this.minSize = minSize;
this.nowSize = minSize;
try {
for (int i = 0; i < minSize; i++) {
MyConnection conn = buildMyConnection();
this.connectionPool.add(conn);
}
}catch (Exception e){
throw new RuntimeException("get connection fail because "+e.getMessage());
}
}
}
3、测试
public static void main(String[] args) throws InterruptedException { MyDataSource dataSource = new MyDataSource("org.postgresql.Driver", "jdbc:postgresql://127.0.0.1:5432/zflow", "postgres","253897"); for(int i=0 ; i<200 ; i++){ Thread.sleep(2); new Thread(()->{ try { MyConnection connection = dataSource.popConnection(); Thread.sleep(20); dataSource.pushConnection(connection); }catch (Exception e){ } }).start(); } }
执行结果打印如下