1.异常
描述
使用的公平锁.开了两个线程,一个线程负责加锁,另一个线程解锁,发生该异常。
相关加锁代码
String redisKey = TrialRedisLockEnum.TRIAL_REDIS_LOCK_ENUM.name().concat(id); RLock locke =redissonClient.getFairLock(redisKey);
locke.lock(60 * 60L, TimeUnit.SECONDS);
相关解锁代码
String redisKey = TrialRedisLockEnum.TRIAL_REDIS_LOCK_ENUM.name().concat(id); RLock locke =redissonClient.getFairLock(redisKey);
System.out.println(locke.isLocked() + "11" + locke.isHeldByCurrentThread());
locke.unlock();
异常信息
attempt to unlock lock, not locked by current thread by node id: 9f178836-f7e1-44fe-a89d-2db52f399c0d thread-id: 22
2.分析原因
redis分布式锁是锁定的当前线程,如果A线程加锁,那么用unlock()方法只能由当前加锁线程解锁。
3.解决办法
在其他线程解锁时,使用强制解锁locke.forceUnlock()
String redisKey = TrialRedisLockEnum.TRIAL_REDIS_LOCK_ENUM.name().concat(id); RLock locke = redisService.getLock(redisKey); System.out.println(locke.isLocked() + "11" + locke.isHeldByCurrentThread()); locke.forceUnlock();
或者取消公平锁,使用可重入锁。
4.参考
https://blog.csdn.net/weixin_39619170/article/details/110986437
https://blog.csdn.net/Yunwei_Zheng/article/details/106480759
https://www.cnblogs.com/nov5026/p/11684632.html
5.扩展
RLock的lock()方法对于公平锁来说必须由持有锁的线程释放锁,才能得到锁,否者线程一致等待,直到获得锁.
两个线程a,b,a加上分布式锁,然后没解锁,b去获得锁,b就会一直等待直到a释放锁,获得锁。