notify()必须在synchronized块中与wait()成对使用,用于唤醒等待空闲连接的线程;归还连接时需先加锁、添加连接再notify,获取连接时须用while循环检查条件并调用wait()。

在 Java 简单连接池实现中,notify() 主要用于唤醒等待空闲连接的线程,但它必须配合 wait() 和正确的同步机制使用,否则无效甚至引发异常。
notify 需要与 wait 成对出现在 synchronized 块中
notify() 本身不会释放锁,也不能脱离同步上下文调用。在连接池中,通常一个线程从连接队列取连接时若为空,会调用 wait() 进入等待;另一个线程归还连接后,调用 notify() 唤醒其中一个等待者。
- 必须在
synchronized块内调用wait()和notify(),且锁对象一致(如连接池的内部锁对象或this) - 推荐用
notifyAll()而非notify(),避免信号丢失或唤醒错线程(尤其在多个等待条件共存时) -
wait()应始终放在 while 循环中判断条件,防止虚假唤醒
典型连接池归还连接时触发 notify
当客户端使用完连接并调用 returnConnection(conn),连接池将连接放回空闲队列,并通知等待线程:
synchronized (lock) {
idleConnections.add(conn);
lock.notify(); // 或 notifyAll()
}
注意:不能在归还前就 notify,否则可能唤醒线程但实际无可用连接;也不能在未加锁时调用,否则抛出 IllegalMonitorStateException。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
立即学习“Java免费学习笔记(深入)”;
获取连接时正确使用 wait 等待
请求连接的线程需检查空闲队列,为空则等待:
synchronized (lock) {
while (idleConnections.isEmpty()) {
try {
lock.wait(); // 释放锁并挂起
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return null;
}
}
return idleConnections.removeFirst();
}
这里 while 是关键——即使被唤醒,也要重新检查条件是否满足,因为可能被其他线程抢先获取了唯一连接。
notify 不解决所有并发问题,需配合其他设计
仅靠 notify 无法保证连接池的健壮性:
- 连接可能失效(网络断开、超时),归还前应做简单校验(如
conn.isValid(1)) - 应限制最大连接数,避免无限创建;超出时新请求也应 wait,而非直接失败
- 建议用
ReentrantLock+Condition替代内置锁,更灵活可控(例如多个等待队列区分读写)

















