redis实现分布式锁

   分布式锁

e0535635a48c41e09b0ebefb41fa7ab3.png

f510bf8260ba4a16a911680ffceb2dc2.png

1.基于redis实现分布式锁

422c57ef7b244ce681b69b8b5ad38e3a.png

注意:这里设置过期时间,是为了预防死锁。如果某个线程获取了锁,但还没等它执行完业务,释放锁。服务器就宕机了,那么就不会有人再去释放锁,出现了死锁问题。

简单业务代码:

public interface ILock {
    boolean tryLock(long timeoutSec);

    //删除锁
    void unLock();
}
public class SimpleRedisLock implements ILock {
    //name 业务名字 (要知道是我哪个业务获取了锁,不可能所有业务获取一把锁啊)
    private String name;

    private StringRedisTemplate stringRedisTemplate;

    private static String KEY_PREFIX = "lock:";

    public SimpleRedisLock(String name, StringRedisTemplate stringRedisTemplate) {
        this.name = name;
        this.stringRedisTemplate = stringRedisTemplate;
    }

    /**
     * 尝试获取锁
     *
     * @param timeoutSec 锁的过期时间
     * @return 是否成功获取锁
     */
    @Override
    public boolean tryLock(long timeoutSec) {
        long threadId = Thread.currentThread().getId();
        String threadName = Thread.currentThread().getName();
        Boolean success = stringRedisTemplate.opsForValue()
                .setIfAbsent(KEY_PREFIX + this.name, threadName + threadId, timeoutSec, TimeUnit.SECONDS);
        //不直接返回success是因为它是Boolean类型(可能为null),返回值是boolean(不能为null),有一个自动拆箱。可能会空指针异常
        return Boolean.TRUE.equals(success);
    }

    @Override
    public void unLock() {
        String threadId = ID_PREFIX + Thread.currentThread().getId();
        String id = stringRedisTemplate.opsForValue().get(KEY_PREFIX + this.name);
        if (id.equals(threadId)) {//只有当我释放锁的线程和我当时获取锁的线程是同一个时,才能释放锁!
            stringRedisTemplate.delete(KEY_PREFIX + this.name);
        }
    }
}

bdd28bd25a50434d9b8624b118d2864a.png

2.基于Redisson实现分布式锁

业务代码:

lua脚本可以保证操作的原子性,类似事务,同时会执行成功/失败。

Redisson实现分布式锁的优点:

1.添加了Watch dog 可以给锁续期。

2.没抢到锁的线程会进行尝试等待。在高并发情况下增加分布式锁的使用性能。

3.所有的redis命令是基于lua脚本完成的。

Redisson实现分布式锁的可重入性

大概流程:底层通过hash结构存储,hash中的key存储的是获取锁的线程id,value是重入的次数。

在一个线程中,每次获取锁,重入次数+1,释放锁,重入次数-1。

对于上述代码:执行add1方法时,第一次获取锁,重入次数为1。执行add2方法中的获取锁,重入次数为2。add2释放锁,重入次数 - 1,为1。add1方法最后释放锁重入次数为0。删除锁信息

小结:

相关推荐

  1. Redis实现分布式

    2024-04-21 10:40:10       44 阅读
  2. Redis分布式实现

    2024-04-21 10:40:10       48 阅读
  3. Redis实现分布式

    2024-04-21 10:40:10       136 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-21 10:40:10       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-21 10:40:10       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-21 10:40:10       82 阅读
  4. Python语言-面向对象

    2024-04-21 10:40:10       91 阅读

热门阅读

  1. C++笔记打卡第18天(vector、deque)

    2024-04-21 10:40:10       26 阅读
  2. c#多线程 使用lock锁

    2024-04-21 10:40:10       36 阅读
  3. CentOS 源码安装 Python3

    2024-04-21 10:40:10       39 阅读
  4. C# 面向对象编程(一)——类 第二篇

    2024-04-21 10:40:10       47 阅读
  5. MySQL中NULL和空的区别是什么?底层原理是什么?

    2024-04-21 10:40:10       43 阅读
  6. Centos sudo权限错误

    2024-04-21 10:40:10       41 阅读
  7. Android10以上MediaProjection截屏

    2024-04-21 10:40:10       98 阅读
  8. 欢迎 Llama 3:Meta 的新一代开源大语言模型

    2024-04-21 10:40:10       31 阅读