分布式锁

228 阅读2分钟

分布式系统是跨虚拟机的,jvm的锁不管用,所以需要分布式锁。

实现的要求有:

1.多进程可见,不然怎么标记

2.避免死锁,就是保证锁可以释放

3.排他

4.服务器宕机怎么补救

实现的方式很多,和java服务独立的有很多东西,比如redis、数据库、zookeeper....

简单记录一种利用redis实现的方法。

1.redis本身就是多服务共享的,满足 2.排他 让他执行 setnx aa bb,这哥们第一次执行会返回1,有了之后执行返回0,返回1我们就知道我们获取到锁了 3.避免死锁 可以给这key设置过期时间,到期自动被删除 4.补救可以利用redis的主从、哨兵

好像不对,随便设置个key-value有问题

为什么,因为比如一个进程A执行,拿到锁,执行比较耗时,结果锁到时间了被删除了,进程B获取到了锁开始执行,然后进程A执行完了,执行del删除锁,然后进程C又获取了。 这有一个问题,不是自己的锁请不要删除,所以可以设置自己的线程Id,aa 线程信息,每次删除前比较下是不是自己的。

还是不对,这锁不是可重入锁,应该使用hash结构

key aa 线程信息 次数,当次数减成0才可以del

还是有问题你的判断逻辑不是原子操作

我觉得可以把逻辑改成lua脚本执行

最后发现已经有Redission了

 @Autowired
 private RedissonClient redissonClient;
 public void test() {
        // 创建锁对象,并制定锁的名称
        RLock lock = redissonClient.getLock("aa");
        // 获取锁,设置自动失效时间为30s
        boolean isLock = lock.tryLock();
        // 判断是否获取锁
        if (!isLock) {
            // 获取失败
            return;
        }
        try {
           
        } catch (InterruptedException e) {
           
        } finally {
            // 释放锁
            lock.unlock();
            
        }
    }