必须在finally中归还jedis实例,因为jedis非线程安全,需独占连接;漏归还会导致连接池耗尽、后续请求阻塞或抛出could not get a resource from the pool异常。

在 finally 块中安全归还 Jedis 连接,核心是确保 jedis.close() 一定被执行,且只对从连接池获取的非 null 实例调用。
为什么必须在 finally 中归还
Jedis 实例本身不是线程安全的,每次使用都应独占一个连接。JedisPool 负责复用连接,但前提是用完后及时归还。如果漏掉归还,连接会一直被占用,池中可用连接数逐渐减少,最终导致后续线程阻塞或抛出 JedisConnectionException: Could not get a resource from the pool。
标准 finally 归还写法
以下是最稳妥、兼容所有 Java 版本(包括不支持 try-with-resources 的旧环境)的写法:
- 声明
Jedis jedis = null在 try 外部 - 在 try 块中调用
pool.getResource()获取实例并执行 Redis 操作 - 在 finally 块中判空后调用
jedis.close()
示例代码:
Jedis jedis = null;
try {
jedis = pool.getResource();
jedis.set("user:1001", "Alice");
String name = jedis.get("user:1001");
} catch (Exception e) {
// 处理业务异常,如网络超时、命令错误等
e.printStackTrace();
} finally {
if (jedis != null) {
jedis.close(); // 实际是归还给池,不是关闭 TCP
}
}
close() 的真实含义
当 Jedis 实例来自 JedisPool 时,调用 close() 并不会断开底层 socket 连接,而是将该连接标记为“空闲”并放回池中,供其他线程复用。这是 JedisPool 设计的关键机制。若误用 new Jedis(...).close(),才会真正关闭连接——那种方式在多线程下绝对禁止。
更简洁的替代方案:try-with-resources
如果你使用 Java 7+,推荐用 try-with-resources,它自动调用 close(),语义清晰、不易遗漏:
- Jedis 类实现了
AutoCloseable接口 - 资源在 try 块结束时(无论是否异常)自动归还
- 无需手动判空和 finally 块
示例:
try (Jedis jedis = pool.getResource()) {
jedis.set("counter", "123");
Long incr = jedis.incr("counter");
} // close() 自动触发,连接归还池中
应用关闭时的收尾动作
整个应用停止前,需显式关闭连接池本身,释放全部连接和线程资源:
- 调用
pool.close()(Jedis 3.0+ 推荐)或pool.destroy()(旧版) - 通常放在 Spring 的
@PreDestroy方法、ServletContextListener 或 JVM Shutdown Hook 中
不关池会导致连接泄漏、端口未释放,重启应用时可能报地址已被占用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











