美文网首页
基于Redisson的分布式锁

基于Redisson的分布式锁

作者: neko_11 | 来源:发表于2019-04-13 17:24 被阅读0次

    1、概述

    什么是分布式锁?在分布式系统中,常常需要协调各个系统的动作,保证事务的一致性或者避免重复执行相同操作。如果不同的系统或是同一个系统的不同主机之间需要共享同一资源,那么系统在访问这些资源的时候,往往需要互斥来防止彼此干扰,避免造成各系统的资源不一致,这个时候,便需要使用到分布式锁。Redisson基于redis提供了我们常用的一些锁。

    redisson官方发布了redisson-spring-boot-starter,具体可以参考:gitHub文档

    redisson最新依赖

    <dependency>
        <groupId>org.redisson</groupId>
        <artifactId>redisson</artifactId>
        <version>3.10.5</version>
    </dependency>
    

    2、特点

    • 互斥:锁的最基本特性,分布式锁需要保证不同节点不同线程互斥。
    • 死锁: 如果一个线程获得锁,但由于某些原因不能释放锁,致使其他线程永远无法获取锁,形成死锁。分布式锁必须做到避免死锁。
    • 性能: 高并发分布式系统中,线程互斥等待可能会造成性能瓶颈,需要开发人员妥善处理。
    • 锁特性:分布式锁不能只是加锁,然后一直等待。最好实现如Java Lock的一些功能如:锁判断,超时设置,可重入性等。

    3、锁类型

    • 可重入锁
      可重入锁指的是可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁。
      Redisson的可重入锁RLock接口继承了java.util.concurrent.locks.Lock接口,支持锁自动过期
        public void ReentrantLock(RedissonClient redisson) {
            RLock lock = redisson.getLock("test");
            try {
                // 加锁
    //            lock.lock();
                // 若没有手动释放锁,10秒钟以后自动解锁
    //            lock.lock(10, TimeUnit.SECONDS);
                // 尝试加锁,最多等待3秒,上锁以后60秒自动解锁
                boolean res = lock.tryLock(3, 60, TimeUnit.SECONDS);
                if (res) { //成功
                    // do something
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                // 手动解锁
                lock.unlock();
            }
        }
    

    RLock继承了org.redisson.api.RLockAsync,支持异步执行

        public void AsynReentrantLock(RedissonClient redisson) {
            RLock lock = redisson.getLock("test");
            try {
    //            lock.lockAsync();
    //            lock.lockAsync(10, TimeUnit.SECONDS);
                Future<Boolean> res = lock.tryLockAsync(3, 60, TimeUnit.SECONDS);
                if (res.get()) {
                    // do something
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
    • 公平锁
      加锁前先查看是否有排队等待的线程,有的话优先处理排在前面的线程,原则是先到先得。保证了当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程。
        public void FairLock(RedissonClient redisson) {
            RLock fairLock = redisson.getFairLock("test");
            try {
    //            fairLock.lock();
    //            fairLock.lock(10, TimeUnit.SECONDS);
                // 尝试加锁,最多等待3秒,上锁以后60秒自动解锁
                boolean res = fairLock.tryLock(3, 60, TimeUnit.SECONDS);
                if (res) { //成功
                    // do something
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                fairLock.unlock();
            }
        }
    
    • 联锁
      RedissonMultiLock对象可以将多个RLock关联为一个联锁,每个RLock对象实例可以来自于不同的Redisson实例。
        public void MultiLock(RedissonClient redisson1,RedissonClient redisson2, RedissonClient redisson3){
            RLock lock1 = redisson1.getLock("lock1");
            RLock lock2 = redisson2.getLock("lock2");
            RLock lock3 = redisson3.getLock("lock3");
            RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3);
            try {
                // 同时加锁lock1 lock2 lock3, 所有的锁都上锁成功才算成功。
                lock.lock();
                // 尝试加锁,最多等待10秒,上锁以后60秒自动解锁
                boolean res = lock.tryLock(10, 60, TimeUnit.SECONDS);
                if (res) { //成功
                    // do something
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
    • 红锁
      RedissonRedLock对象实现了RedLock的加锁算法,其也可以将多个RLock对象关联为一个红锁,每个RLock对象实例可以来自于不同的Redisson实例。
    public void RedLock(RedissonClient redisson1, RedissonClient redisson2, RedissonClient redisson3) {
            RLock lock1 = redisson1.getLock("lock1");
            RLock lock2 = redisson2.getLock("lock2");
            RLock lock3 = redisson3.getLock("lock3");
            RedissonRedLock lock = new RedissonRedLock(lock1, lock2, lock3);
            try {
                // 同时加锁:lock1 lock2 lock3, 红锁在大部分节点上加锁成功就算成功。
                lock.lock();
                // 尝试加锁,最多等待10秒,上锁以后60秒自动解锁
                boolean res = lock.tryLock(10, 60, TimeUnit.SECONDS);
                if (res) { //成功
                    // do something
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
    • 读写锁
      Redisson的分布式可重入读写锁RReadWriteLock继承了java.util.concurrent.locks.ReadWriteLock
      该对象允许同时有多个读取锁,但是最多只能有一个写入锁。
    public void ReadLock(RedissonClient redisson){
            RReadWriteLock rwlock = redisson.getReadWriteLock("test");
            try {
                rwlock.readLock().lock();
                // 10秒钟以后自动解锁
                rwlock.readLock().lock(10, TimeUnit.SECONDS);
                // 尝试加锁,最多等待10秒,上锁以后60秒自动解锁
                boolean res = rwlock.readLock().tryLock(10, 60, TimeUnit.SECONDS);
                if (res) { //成功
                    // do something
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                rwlock.readLock().unlock();
            }
        }
    
        public void WriteLock(RedissonClient redisson){
            RReadWriteLock rwlock = redisson.getReadWriteLock("test");
            try {
                rwlock.writeLock().lock();
                // 10秒钟以后自动解锁
                rwlock.writeLock().lock(10, TimeUnit.SECONDS);
                // 尝试加锁,最多等待10秒,上锁以后60秒自动解锁
                boolean res = rwlock.writeLock().tryLock(10, 60, TimeUnit.SECONDS);
                if (res) { //成功
                    // do something
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                rwlock.writeLock().unlock();
            }
        }
    

    相关文章

      网友评论

          本文标题:基于Redisson的分布式锁

          本文链接:https://www.haomeiwen.com/subject/dzzsiqtx.html