redis分布式锁的实现

本文详细介绍了Redis分布式锁的实现,包括参数说明、流程图解析和关键函数的介绍。文章提到了分布式锁的超时时间、重试次数和睡眠时间等配置,并通过代码展示了如何尝试获取和刷新锁,以及在未成功获取锁时的重试机制。
摘要由CSDN通过智能技术生成

一些参数说明
  1. DynmaicConfigurerBean:项目中配置,方便获取动态属性。
  2. 分布式锁相关的属性有:分布式锁的超时时间、重试次数、睡眠时间等
  3. 超时时间默认1s,重试次数默认5次,睡眠时间默认200ms
流程图

在这里插入图片描述

流程图及关键函数说明
  1. long expires = System.currentTimeMillis() + timeout + 1;

    设置分布式锁的超时时间

  2. redisClient.setNX(lockKey, expiresStr)

    尝试获取锁,键为锁的名字,值为超时时间

    如果获取成功就返回。

    没有获取会走下面逻辑:分析

/**
 1. 对于以下部分场景考虑的【重要注释】:
 2. ① 某一时刻所有线程都检测到之前已经成功获取锁的线程已经持有锁。
 3.   此时,如果检测到已持有锁的线程已经锁超时,那么他们可以通过CAS机制竞争锁,可以保证只有一个线程获取锁。
 4. ② 某一时刻,之前有一个线程已经获取锁了,剩余的线程,会发现锁的生命周期结束时间大于当前时间,因此不会获取锁。
 5. ③判断过期时间的好处:如果在发布时的时候,或者因为某些原因机器崩溃,假设碰巧没有解锁,那么就会产生死锁,判断过期时间也有自动检测死锁的功能。
 6. ④ 对于多线程getSet会不会让锁的生存周期结束时间更新?首先,即使更新,分布式锁的判断依据是是否获取锁,并不关心超时的情况,并且对于已经获取锁
 7.    的线程会解锁。即使已经获取锁的线程超时了,但是对应key值的value值已经被重新赋值生命周期,但是因为既然是锁竞争,走到这里他们的生存周期的截止时间
 8.    都是相近的,也没有什么问题。
 */
  1. String currentValueStr = redisClient.get(lockKey);
Long.parseLong(currentValueStr) < System.currentTimeMillis()

没有获取到锁则获取该锁的超时时间,判断超时时间有没有超过当前时间
  1. String oldValueStr = redisClient.getSet(lockKey, expiresStr);

    如果已经小于当前时间,说明获得锁的线程并没有及时释放锁,则去cas抢锁,抢锁成功,则返回

  2. 没有抢到,则重试次数加1,重试次数大于阈值,则退出,否则睡眠一段时间再重试。

代码实现
@Component
public class DistributedLock {
   
    private Logger logger = LoggerFactory.getLogger(DistributedLock.class);

    /** 动态配置中分布式锁是否生效的标识 */
    private static final String distributedLockValid = "distributedLockValid";
    /** 动态配置中分布式锁的超时时间 */
    private static final String distributedLockTimeout = "distributedLockTimeout";
    /** 动态配置中分布式锁的重试次数 */
    private static final String distributedLockRetryCount = "distributedLockRetryCount";
    /** 动态配置中分布式锁的睡眠时间 */
    private static final String distributedLockSleepTime = "distributedLockSleepTime";

    @Autowired
    private DynmaicConfigurerBean dynmaicConfigurerBean;

    @Resource(name = "redisClient")
    private RedisClient redisClient;

    /**
     * 分布式锁-加锁[ms]级别加锁
     * 
     * @param logHead 日志头
     * @param lockKey key
     * @return lockBean
     */
    public LockBean lock(String logHead, String lockKey) {
   
        try 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值