zoukankan      html  css  js  c++  java
  • Redisson

    Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service) Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。

    本文我们仅关注分布式锁的实现,更多请参考官方文档

    (1) 环境搭建
    导入依赖

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

      

    开启配置https://github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95

    @Configuration
    public class MyRedisConfig {
    
        @Value("${ipAddr}")
        private String ipAddr;
    
        // redission通过redissonClient对象使用 // 如果是多个redis集群,可以配置
        @Bean(destroyMethod = "shutdown")
        public RedissonClient redisson() {
            Config config = new Config();
            // 创建单例模式的配置
            config.useSingleServer().setAddress("redis://" + ipAddr + ":6379");
            return Redisson.create(config);
        }
    }
    

      

    (2) 可重入锁(Reentrant Lock)

    分布式锁:github.com/redisson/redisson/wiki/8.-分布式锁和同步器

    A调用B。AB都需要同一锁,此时可重入锁就可以重入,A就可以调用B。不可重入锁时,A调用B将死锁

    // 参数为锁名字
    RLock lock = redissonClient.getLock("CatalogJson-Lock");//该锁实现了JUB.locks.lock接口
    lock.lock();//阻塞等待
    // 解锁放到finally // 如果这里宕机:有看门狗,不用担心
    lock.unlock();
    

      

    基于Redis的Redisson分布式可重入锁RLock Java对象实现了java.util.concurrent.locks.Lock接口。同时还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口。
    
    大家都知道,如果负责储存这个分布式锁的Redisson节点宕机以后,而且这个锁正好处于锁住的状态时,这个锁会出现锁死的状态。为了避免这种情况的发生,Redisson内部提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期。默认情况下,看门狗的检查锁的超时时间是30秒钟(每到20s就会自动续借成30s,是1/3的关系),也可以通过修改Config.lockWatchdogTimeout来另行指定。
    

      

    // 加锁以后10秒钟自动解锁,看门狗不续命
    // 无需调用unlock方法手动解锁
    lock.lock(10, TimeUnit.SECONDS);
    
    // 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
    boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
    if (res) {
       try {
         ...
       } finally {
           lock.unlock();
       }
    }
    如果传递了锁的超时时间,就执行脚本,进行占锁;
    如果没传递锁时间,使用看门狗的时间,占锁。如果返回占锁成功future,调用future.onComplete();
    没异常的话调用scheduleExpirationRenewal(threadId);
    重新设置过期时间,定时任务;
    看门狗的原理是定时任务:重新给锁设置过期时间,新的过期时间就是看门狗的默认时间;
    锁时间/3是定时任务周期;
    

      

  • 相关阅读:
    桟错误分析方法
    gstreamer调试命令
    sqlite的事务和锁,很透彻的讲解 【转】
    严重: Exception starting filter struts2 java.lang.NullPointerException (转载)
    eclipse 快捷键
    POJ 1099 Square Ice
    HDU 1013 Digital Roots
    HDU 1087 Super Jumping! Jumping! Jumping!(动态规划)
    HDU 1159 Common Subsequence
    HDU 1069 Monkey and Banana(动态规划)
  • 原文地址:https://www.cnblogs.com/vincentmax/p/14481428.html
Copyright © 2011-2022 走看看