自定义连接池 可扩容

本文介绍了一种自定义实现的简单连接池,具备初始化固定连接数、按需自动扩容至最大限制以及在连接释放后能收缩回初始大小的功能。然而,该实现存在线程不安全问题,获取连接失败时无等待机制,并且如果连接长期被占用,连接池效能会降低。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自定义实现了一个简单的连接池

已实现功能:

  • 通过给定的初始大小,初始化固定数量的连接池。
  • 通过maxsize指定最大连接池大小,当初始连接数不够用时,自动扩容,但不超过maxsize。
  • 扩容之后若连接占用减少,连接池自动恢复到初始大小

(想到但)未实现功能:

  • 线程不安全
  • 获取连接失败无等待时间,直接给出异常。
  • 如果线程池初始大小连接被长期占用,那么该线程池将毫无卵用。
package jdbc;

import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;

public class MyDataSource {
    private LinkedList<Connection> pool = new LinkedList<>(); // 存储连接的容器
    private int initSize; // 初始连接池大小
    private int maxSize; // 最大连接池大小
    private int correctSize = 0; // 当前连接池大小,不是当前连接数量。

    // 初始化
    public MyDataSource(int initSize, int maxSize) {
        this.initSize = initSize;
        this.maxSize = maxSize;
        for (int i = 0; i < initSize; i++) {
            pool.add(this.createConnection());
            correctSize++;
        }
    }

    public Connection getConnection() {
        // 如果连接池没有空,从连接池去连接
        if (!pool.isEmpty()) {
            return pool.remove();
        } else if (correctSize < maxSize) { // 如果连接池空了但当先连接池大小小于最大值,那么新建连接并扩充连接池。
            correctSize++;
            return this.createConnection();
        }
        // 到这说明连接以达到最大,直接抛异常
        throw new RuntimeException("连接池已满!");
    }

    private Connection createConnection() {
        Connection connection = JDBCUtils.getConnection();
        // 给出的是connection的代理对象,这里我们只增强了close方法。
        return (Connection) Proxy.newProxyInstance(
                connection.getClass().getClassLoader(),
                new Class[]{Connection.class},
                (proxy1, method, args) -> {
                    Object result = null;
                    // 当调用close方法的时候
                    if (method.getName().equals("close")) {
                        // 如果连接池内连接数量小于初始数量,就归还连接
                        if (pool.size() < initSize) {
                            pool.add((Connection) proxy1);
                            System.err.println("池内连接数量:" + pool.size() +
                                    " 当前池大小:" + correctSize +
                                    " 归还连接。。。");
                        } else { // 否则说明该连接为临时扩充所得,直接关闭连接并修改当前连接池大小。
                            method.invoke(connection, args);
                            correctSize--;
                            System.err.println("池内连接数量:" + pool.size() +
                                    " 当前池大小:" + correctSize +
                                    " 关闭连接。。。");
                        }
                    } else
                        result = method.invoke(connection, args);
                    return result;
                }
        );
    }

    public static void main(String[] args) throws SQLException {
        MyDataSource myDataSource = new MyDataSource(3, 5);
        Connection connection = myDataSource.getConnection();
        Connection connection1 = myDataSource.getConnection();
        connection1.close();
        Connection connection2 = myDataSource.getConnection();
        Connection connection3 = myDataSource.getConnection();
        connection3.close();
        Connection connection4 = myDataSource.getConnection();
        Connection connection5 = myDataSource.getConnection();
        Connection connection6 = myDataSource.getConnection();
        connection6.close();
        connection5.close();
        connection4.close();
        connection2.close();
    }
}

附上JDBCUtils的代码

package jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ResourceBundle;

public class JDBCUtils {
    // JDBC四打参数
    private static String driverClass;
    private static String url;
    private static String username;
    private static String password;
    // 静态代码块,使加载驱动类只执行一次
    static {
        try {
            // 加载配置文件获取数据
            ResourceBundle bundle = ResourceBundle.getBundle("db");
            driverClass = bundle.getString("driverClass");
            url = bundle.getString("url");
            username = bundle.getString("username");
            password = bundle.getString("password");
            // 加载驱动类
            Class.forName(driverClass);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static Connection getConnection(){
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url,username,password);
        }catch (Exception e){
            e.printStackTrace();
        }
        return conn;
    }

}

输出结果

从结果可以看出,当池大小不够时可以自动扩容到最大池大小。

调用关闭连接时,如果当前池大小是扩容的,还可以收缩回初始大小。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值