当前位置:首页 > IT技术 > 其他 > 正文

Redisson
2022-08-30 00:02:23

https://github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95#26-%E5%8D%95redis%E8%8A%82%E7%82%B9%E6%A8%A1%E5%BC%8F
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.14.1</version>
</dependency>

以配置类的形式设置

 

 

@Configuration
public class MyRedisConfig {
    
    @Bean
    public RedissonClient redissonClient(){
        Config config = new Config();
        //配置链接的信息
        config.useSingleServer().setAddress("redis://192.168.1.137:6379");
        RedissonClient redissonClient = Redisson.create();
        return redissonClient;
    }
}

ls -l /proc/7579/cwd
接下来我们看 分布式锁 的可重入锁(Reentrant Lock) 同一个对象的同一把锁 是可以进入

 

 @ResponseBody
    @GetMapping("/hello")
    public String hello(){
        RLock myLock = redissonClient.getLock("myLock");
        // 加锁
       // myLock.lock();
        //通过效果演示我们可以发现  指定了过期时间后  自动续期就不会生效了  这时我们就需要注意设置过期时间一定要满足我们得业务场景     默认情况下,看门狗的检查锁的超时时间是30秒钟,也可以通过yml修改Config.lockWatchdogTimeout来另行指定
    另外Redisson还通过加锁的方法提供了leaseTime的参数来指定加锁的时间。超过这个时间后锁便自动解开了。
    
// 加锁以后10秒钟自动解锁
// 无需调用unlock方法手动解锁
lock.lock(10, TimeUnit.SECONDS);

// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
   try {
     ...
   } finally {
       lock.unlock();
   }
}
//如果我们指定了锁的过期时间 那么在源码中会直接帮我们创建一个过期时间是指定的锁  时间到期后就会把该锁删除
        //如果我们没有指定过期时间 那么在执行的时候 首先会创建一把锁且过期时间是30秒  然后会创建异步任务  每隔10秒 去执行任务来续期
        //实际开发中 我们最好指定过期时间---》性能考虑--》计算代码的执行时间
        myLock.lock(10, TimeUnit.SECONDS);//过期时间是10s  业务时间超过10s 会不会自动续期
        try {
            System.out.println("加锁成功...业务处理....." + Thread.currentThread().getName());
            Thread.sleep(30000);
        }catch (Exception e){
        
        }finally {
            System.out.println("释放锁成功..." +  Thread.currentThread().getName());
            // 释放锁
            myLock.unlock();
        }
        return "hello";
    }
公平锁(Fair Lock)保证了当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程。所有请求线程会在一个队列中排队,当某个线程出现宕机时,
Redisson会等待5秒后继续下一个线程,也就是说如果前面有5个线程都处于等待状态,那么后面的线程会等待至少25秒。

RLock fairLock = redisson.getFairLock("anyLock");
// 最常见的使用方法
fairLock.lock();

大家都知道,如果负责储存这个分布式锁的Redis节点宕机以后,而且这个锁正好处于锁住的状态时,这个锁会出现锁死的状态。为了避免这种情况的发生,Redisson内部提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期。默认情况下,看门狗的检查锁的超时时间是30秒钟,也可以通过修改Config.lockWatchdogTimeout来另行指定。

另外Redisson还通过加锁的方法提供了leaseTime的参数来指定加锁的时间。超过这个时间后锁便自动解开了。


// 10秒钟以后自动解锁
// 无需调用unlock方法手动解锁
fairLock.lock(10, TimeUnit.SECONDS);

// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
boolean res = fairLock.tryLock(100, 10, TimeUnit.SECONDS);
...
fairLock.unlock();
读写锁(ReadWriteLock)分布式可重入读写锁允许同时有多个读锁和一个写锁处于加锁状态。
RReadWriteLock rwlock = redisson.getReadWriteLock("anyRWLock");
// 最常见的使用方法
rwlock.readLock().lock();
// 或
rwlock.writeLock().lock();

大家都知道,如果负责储存这个分布式锁的Redis节点宕机以后,而且这个锁正好处于锁住的状态时,这个锁会出现锁死的状态。为了避免这种情况的发生,Redisson内部提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期。默认情况下,看门狗的检查锁的超时时间是30秒钟,也可以通过修改Config.lockWatchdogTimeout来另行指定。

另外Redisson还通过加锁的方法提供了leaseTime的参数来指定加锁的时间。超过这个时间后锁便自动解开了。

// 10秒钟以后自动解锁
// 无需调用unlock方法手动解锁
rwlock.readLock().lock(10, TimeUnit.SECONDS);
// 或
rwlock.writeLock().lock(10, TimeUnit.SECONDS);

// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
boolean res = rwlock.readLock().tryLock(100, 10, TimeUnit.SECONDS);
// 或
boolean res = rwlock.writeLock().tryLock(100, 10, TimeUnit.SECONDS);
...
lock.unlock();
-------------------------------------------------------------
根据业务操作我们可以分为读写操作,读操作其实不会影响数据,那么如果还对读操作做串行处理,效率会很低,这时我们可以通过读写锁来解决这个问题
在读写锁中,只有读读的行为是共享锁,相互之间不影响,只要有写的行为存在,那么就是一个互斥锁(排他锁)
---------------------------------------------------------------------------------------------
   @GetMapping("/write")
    @ResponseBody
    public String writeValue(){
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rw-lock");
        //加写锁
        RLock rLock = readWriteLock.writeLock();
        String s=null;
        rLock.lock();
        try {
            System.out.println("写锁成功");
             s = UUID.randomUUID().toString();
             stringRedisTemplate.opsForValue().set("msg", s);
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            rLock.unlock();
        }
    return s;
    
    }
    
    /**
     * 读读操作 相当于没有加锁
     * 写 读操作  需要等待写锁释放 读锁才能读取  阻塞
     * 写 写  阻塞方式
     * 读写  读数据的时候也会添加锁  那么写的行为也会阻塞
     * @return
     */
    @GetMapping("/read")
    @ResponseBody
    public String readValue(){
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rw-lock");
        //加读锁
        RLock rLock = readWriteLock.readLock();
        rLock.lock();
        String s = null;
        try {
            System.out.println("读锁成功");
            s = stringRedisTemplate.opsForValue().get("msg");
            Thread.sleep(30000);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        //    rLock.unlock();
        }
        return s;
    
    }
    

 

闭锁
基于Redisson的Redisson分布式闭锁

  @ResponseBody
    @GetMapping("/lockDoor")
    public String lockDoor() {
        RCountDownLatch door = redissonClient.getCountDownLatch("door");//阻塞 等待count 等于0 时才能继续执行
        door.trySetCount(5);
        try {
            door.await();//阻塞等待5个执行完
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "关门熄灯";
    }
    
    @GetMapping("/goHome/{id}")
    @ResponseBody
    public String goHome(@PathVariable  Long id){
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.countDown();
    
        return id+"下班走人";
    }
信号量(Semaphore)
基于Redis的Redisson的分布式信号量    限流
@GetMapping("/park")
    @ResponseBody
    public String park(){
        RSemaphore park = redissonClient.getSemaphore("park");
        boolean b = true;
        try {
            // park.acquire(); // 获取信号 阻塞到获取成功
            b = park.tryAcquire();// 返回获取成功还是失败
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "停车是否成功:" + b;
    }

    @GetMapping("/release")
    @ResponseBody
    public String release(){
        RSemaphore park = redissonClient.getSemaphore("park");
        park.release();
        return "释放了一个车位";
    }

 

本文摘自 :https://www.cnblogs.com/

开通会员,享受整站包年服务立即开通 >