ALittle_study 2021-07-27 15:49 采纳率: 100%
浏览 94
已结题

redis分布式锁一下情况怎么解决

/**
 * @param lockName 锁名称/路径
 * @param waitTime 锁获取等待时间 秒 传空默认10秒
 * @param lockTime 最长加锁时间 秒 传空默认5*60秒
 * @return
 * @describe: 获取一个锁,如果是没有加锁,则会直接获得,如果加锁,会根据等待时间获取锁
 * @author: jiahong.xing/
 * @version: v1.0
 * @date 2018/8/21/021 15:13
 */
public static boolean getLock(String lockName, Integer waitTime, Integer lockTime) {
    if (StringUtils.isEmpty(lockName)) {
        return false;
    }
    if (null == waitTime) {
        waitTime = maxWaitTime;
    }
    if (null == lockTime) {
        lockTime = maxLockTime;
    }
    Long wTime = System.currentTimeMillis() + (waitTime * 1000);
    try {
        while (true) {
            Long inTime = System.currentTimeMillis();
            //如果当前时间大于设置值,则跳出等待
            if (inTime >= wTime) {
                return false;
            }
            boolean isok = RedisUtil.redisTemplate.execute(new RedisCallback<Boolean>() {
                @Override
                public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                    return connection.setNX(lockName.getBytes(), lockName.getBytes());
                }
            });
            if (isok) {
                //所有加锁成功的,均在线程数据里面增加一条,可以在清理线程数据的时候进行解锁,同时也可以手动解锁
                synchronized (Thread.currentThread()) {
                    SessionRdsLockData.add(lockName);
                }
                RedisUtil.redisTemplate.expire(lockName, lockTime, TimeUnit.SECONDS);
                return true;
            }
            //设置等待时间,不无限请求redis
            Thread.sleep(200);
        }
    } catch (Exception e) {
        e.printStackTrace();
        //获取锁失败
        log.error("获取锁失败:{}", lockName);
        return false;
    }
}

//解锁
public static void unLock(String lockName) {
    if (StringUtils.isEmpty(lockName)) {
        return;
    }
    RedisUtil.remove(lockName);
    SessionRdsLockData.remove(lockName);
}
// 删除对应的value
  public static void remove(final String key) {
    if (exists(key)) {
      redisTemplate.delete(key);
  }

假如A线程获取到锁的线程在指定时间内没有完成,key就会被删除,那么B线程就可以获取到锁,那么A执行unLock方法删除的不就是B线程的key了么,那么多线程情况下就会出现锁不住的情况了把?

  • 写回答

4条回答 默认 最新

  • 没事干写博客玩 2021-07-28 00:26
    关注

    你想问的是带时间限制,移除锁的时候想判断是不是已经自动过期。可能其他线程获取到锁,结果被自己删除,导致的幂等性问题吧,用watch解决,我文章里有写,看个思路就行

    https://blog.csdn.net/slslslyxz/article/details/105549341?utm_source=app&app_version=4.12.0&code=app_1562916241&uLinkId=usr1mkqgl919blen

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 8月5日
  • 已采纳回答 7月28日
  • 创建了问题 7月27日

悬赏问题

  • ¥20 请问这种量表怎么用spss量化分析(作为中介模型的因变量
  • ¥55 AD844 howland电流源如何驱动大额负载
  • ¥15 C++ /QT 内存权限的判断函数列举
  • ¥15 深度学习GFnet理解问题
  • ¥15 单细胞小提琴堆叠图代码
  • ¥50 升级strust2版本到2.3.15.1后使用ognl3.0.6.jar windows环境中没有问题,但部署到linux环境报错
  • ¥15 vue页面,node封装接口
  • ¥15 求TMS320F280039C工程模板!
  • ¥15 delphi+fastreport实现分组补空打印问题
  • ¥15 使用python把两台mysql数据库服务器数据导出和导入