请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

一个Redis Pool神奇的现象

private ThreadLocal<Jedis> local = new ThreadLocal<Jedis>();

//这是我的getConnection方法
public Jedis getConn() {
        Jedis jedis = local.get();
        if (jedis == null) {
            if (jedisPool == null) {
                initPool();
            }
            jedis = jedisPool.getResource();
            local.set(jedis);
        } 
        return jedis;
    }
//这是我的closeConn方法
public void closeConn() {
        // 从线程本地获取redis连接对象
        Jedis jedis = local.get();
        if (jedis != null) {
            System.out.println("不为空,关闭");
            jedis.close();
        }
        local.set(null);
    }

奇怪的是,我在线程里面调用了redisPoolUtil.closeConn();之后,调用jedis.set(“1”, “2”);仍然会成功,好像这里的closeConn并没有生效,希望老师坐下解答。一下是我的调用完整步骤

@Autowired
RedisPoolUtil redisPoolUtil;

@GetMapping("/simulateRedisKV")
    public JSONObject simulateRedisManyKV() {
        Jedis jedis = redisPoolUtil.getConn();
        jedis.set("1", "2");
        redisPoolUtil.closeConn();
        // 依然会成功
        jedis.set("2", "2");
        return CommonUtil.successJson("Success");
    }

正在回答 回答被采纳积分+3

1回答

Jimin 2019-02-27 23:33:02

你好,如果你closeconn方法里local.get方法返回空,就会执行不到实际的jedis.close方法了,主流程里的jedis和closeconn里的jedis我理解可能根本就不是一个实例。这个代码里threadlocal域的变量竟然不是static的,我感觉你上层的封装是有问题的,很可能是threadlocal用错了,你沿着这个思路去查一下吧。

0 回复 有任何疑惑可以回复我~
  • 提问者 高秋 #1
    谢谢老师。我已经已经验证过了,主流程和closeconn从threadlocal获取的是同一个jedis对象。这里的threadlocal我是放在redisPoolUtil bean单例里面的,应该只会有一个threadlocal(达到static同样的效果)。这里试了下,直接调用主流程的jedis.close()之后,jedis也依然可以使用。感觉是不是jedis.close()其实并没有真正地关闭连接?
    回复 有任何疑惑可以回复我~ 2019-02-27 23:51:39
  • Jimin 回复 提问者 高秋 #2
    这个问题你可以看一下jedis那个对象调用close方法前后内部属性的变化,如果没释放会有问题,操作不当会带来内存泄漏
    回复 有任何疑惑可以回复我~ 2019-03-05 23:25:44
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信