简易JDBC连接池用LinkedList存连接,ReentrantLock+Condition实现线程安全的阻塞获取与归还; getConnection()支持超时等待,releaseConnection()校验isValid并唤醒等待者;需设非自动提交、防重复关闭、驱动自动加载。

手动实现一个简易 JDBC 连接池,核心是复用 Connection 对象、避免频繁创建销毁、控制并发访问,并保证连接可用性。不需要依赖 HikariCP 或 Druid,用基础 Java 就能搭出可运行的最小原型。
1. 定义连接池的基本结构
一个最简连接池需包含:连接容器(如 LinkedList)、最大/最小连接数、数据库配置、线程安全控制。不追求高级功能(如自动重连、连接泄漏检测),先让“借-还”流程跑通。
- 用
LinkedList<Connection>存活连接,头部取、尾部放,O(1) 操作 - 用
ReentrantLock+Condition控制多线程等待(比synchronized更灵活) - 初始化时预建若干连接(比如 3 个),后续按需增长,上限设为 10
2. 实现 getConnection():支持阻塞获取
当池中无空闲连接时,线程应等待,而不是直接抛异常或返回 null。这是区别于简单对象池的关键。
- 加锁后检查池是否非空,有则弹出并返回
- 为空且当前连接数未达上限,就新建一个
Connection并返回 - 为空且已达上限,调用
condition.await()挂起,等其他线程归还 - 设置合理超时(如 3 秒),避免永久等待
3. 实现 releaseConnection():安全归还并唤醒等待者
归还不是简单 add 到列表——必须检查连接是否还有效,否则会把失效连接塞回池里,导致后续调用失败。
立即学习“Java免费学习笔记(深入)”;
- 调用
connection.isValid(2)验证活跃性(需 JDBC 4.0+) - 若失效,跳过归还,直接
close()释放资源 - 若有效,加入池尾部,并调用
condition.signal()唤醒一个等待线程 - 归还操作也需在锁内完成,保证线程安全
4. 补充关键细节:避免常见坑
简易版不等于随便写,几个地方不处理就会立刻翻车:
-
连接必须设为非自动提交:归还前执行
conn.setAutoCommit(true),否则事务状态残留影响下个使用者 -
统一关闭物理连接:在池销毁或连接失效时调用
conn.close(),不能只清引用 -
防止重复归还:可给 Connection 包一层代理(如
Proxy.newProxyInstance),拦截第二次 close 调用 -
静态加载驱动已过时:用
DriverManager.getConnection(url, props)即可,JDBC 4.0+ 自动服务发现
不复杂但容易忽略。写完后用两个线程交替获取/归还,再模拟网络断开测试 isValid,就能验证基本可用性。


















