• 8.2. 公平锁(Fair Lock)

    8.2. 公平锁(Fair Lock)

    基于Redis的Redisson分布式可重入公平锁也是实现了java.util.concurrent.locks.Lock接口的一种RLock对象。同时还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口。它保证了当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程。所有请求线程会在一个队列中排队,当某个线程出现宕机时,Redisson会等待5秒后继续下一个线程,也就是说如果前面有5个线程都处于等待状态,那么后面的线程会等待至少25秒。

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

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

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

    1. // 10秒钟以后自动解锁
    2. // 无需调用unlock方法手动解锁
    3. fairLock.lock(10, TimeUnit.SECONDS);
    4. // 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
    5. boolean res = fairLock.tryLock(100, 10, TimeUnit.SECONDS);
    6. ...
    7. fairLock.unlock();

    Redisson同时还为分布式可重入公平锁提供了异步执行的相关方法:

    1. RLock fairLock = redisson.getFairLock("anyLock");
    2. fairLock.lockAsync();
    3. fairLock.lockAsync(10, TimeUnit.SECONDS);
    4. Future<Boolean> res = fairLock.tryLockAsync(100, 10, TimeUnit.SECONDS);