redission分布式锁避坑指南

常见用法

RLock lock = redisson.getLock("anyLock");

try{

// 1. 最常见的使用方法

//lock.lock();

// 2. 支持过期解锁功能,10秒钟以后自动解锁, 无需调用unlock方法手动解锁

//lock.lock(10, TimeUnit.SECONDS);

// 3. 尝试加锁,最多等待3秒,上锁以后10秒自动解锁

boolean res = lock.tryLock(3, 10, TimeUnit.SECONDS);

if(res){ //成功

// do your business

}

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

lock.unlock();

}

参数含义

lock.tryLock(long waitTime, long leaseTime, TimeUnit unit)

前两个参数分别是等待锁时间、超时自动释放时间

坑一

超时施放时间

就是说 A拿到了锁之后, 如果发生了一些异常错误,内部业务没能正常的执行,没能正常执行释放锁的操作,这个时候这个超时施放时间才会起作用,也就是说,在A抢到锁之后,即便A的业务出现了堵塞,但是只要没发生一些异常情况,这里的超时施放时间是不起作用的,因为只要不发生异常,内部就会有一个 看门狗,每隔 超时施放时间/3就会刷新一次锁的过期时间(是一个定时任务),确保A能够执行完成业务,当然,A执行完业务后,会删除刷新有效期的定时任务。所以说,超时释放时间在正常执行业务的时候,是不发挥作用的,只在出现异常的时候才会起作用。

坑二

锁释放

常见用法中,会导致锁被其他线程释放。正常线程一持有锁,线程二在等待时间内未获取到锁,会先走到finally语句中,把当前的锁释放掉,然后return。如果再有线程三进来,发现锁已经被释放了,但是线程一还在执行,就会导致并发问题,所以正确的用法是应该判断当前线程是不是锁的持有者,再释放。

正确示例

RLock lock = redisson.getLock("anyLock");

try{

// 1. 最常见的使用方法

//lock.lock();

// 2. 支持过期解锁功能,10秒钟以后自动解锁, 无需调用unlock方法手动解锁

//lock.lock(10, TimeUnit.SECONDS);

// 3. 尝试加锁,最多等待3秒,上锁以后10秒自动解锁

boolean res = lock.tryLock(3, 10, TimeUnit.SECONDS);

if(res){ //成功

// do your business

}

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

if (lock.isHeldByCurrentThread() && lock.isLocked()) {

lock.unlock();

}

}

你可能感兴趣的:(分布式)