分布式锁Redisson之读写锁

简介

保证一定能读到最新数据,修改期间写锁是互斥锁(排他锁)。读锁是一个共享锁

  • 写锁没释放读就必须等待
  • 读 + 读:相当于无锁,并发读只会在Redis中记录好,所有当前的读锁。它们都会同时加锁成功
  • 写 + 读:等待写锁释放
  • 写 + 写:阻塞方式
  • 读 + 写:有读锁,写也需要等待
  • 只要有写* 锁的时候,都得等待

简单用法

分布式可重入读写锁允许同时有多个读锁和一个写锁处于加锁状态。

RReadWriteLock rwlock = redisson.getReadWriteLock("anyRWLock");
// 最常见的使用方法
rwlock.readLock().lock();
// 或
rwlock.writeLock().lock();

另外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();

测试

 /**
     * 写锁
     *
     * @return
     */
    @GetMapping("/write")
    @ResponseBody
    public String writeLock() {
        String s = "";
        RReadWriteLock readWriteLock = redisson.getReadWriteLock("rw-lock");
        RLock rLock = readWriteLock.writeLock();
        try {
		  //1、改数据加写锁,读数据加读锁
            rLock.lock();
            s = UUID.randomUUID().toString();
            redisTemplate.opsForValue().set("writeValue", s);
            Thread.sleep(30000);

        } catch (Exception e) {

        } finally {
            rLock.unlock();
        }

        return s;
    }

    /**
     * 读锁
     * @return
     */
    @GetMapping("/read")
	@ResponseBody
    public String readLock() {

        RReadWriteLock readWriteLock = redisson.getReadWriteLock("rw-lock");
        RLock rLock = readWriteLock.readLock();
        String s = "";
        try {
		    //加读锁
            rLock.lock();
            s = redisTemplate.opsForValue().get("writeValue");
        } catch (Exception e) {

        } finally {
            rLock.unlock();
        }
        return s;
    }

测试:
在redis中新建一个键值对用来测试读
image

读取成功
image

当我们去写的时候,发现读的接口一直在转圈加载,这说明我们写锁生效了,读锁被阻塞等待了,当写锁执行完释放锁,读锁才能执行。
image

image
并且当写锁执行业务进行更新时,我们的读锁读到的是最新的数据。
image

posted @ 2022-11-17 09:14  长情c  阅读(1266)  评论(0)    收藏  举报