在某些场景中,多个进程必须以互斥的方式独占共享资源,这时用分布式锁是最直接有效的。
什么是锁锁是用来控制对共享资源文件独占访问权限的类,当其中一个线程获取了对象锁,在释放掉锁之前,其他线程是没有办法对该资源进行访问的。所以每次仅有一个线程可以获取锁,其他线程只能等待锁的释放再抢占锁。
Redission分布式锁trylocktryLock()方法是有返回值的,它表示用来尝试获取锁
如果获取成功,则返回true
如果获取失败(即锁已被其他线程获取),则返回false
这个方法无论如何都会立即返回。在拿不到锁时不会一直在那等待
加锁和解锁 加锁boolean res = rLock.tryLock(waitTimeout, leaseTime, TimeUnit.SECONDS);
举例:
private RedissonClient redissonClient; public boolean tryLock(String lockKey, long lockWaitTime, long lockTime) { RLock lock = redissonClient.getLock(lockKey); try { // 第一个参数lockWaitTime是等待时间,n毫秒内获取不到锁,则直接返回 // 第二个参数lockTime是锁超时时间,m毫秒后强制释放锁 return lock.tryLock(lockWaitTime, lockTime, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { String msg = String.format("LOCK FAILED: key=%s||tryLockTime=%s||lockExpiredTime=%s", lockKey, lockWaitTime, lockTime); throw new IllegalStateException(msg, e); } }解锁
public void unlock(String lockKey) { try { RLock lock = redissonClient.getLock(lockKey); if (lock != null) { lock.unlock(); } } catch (Throwable e) { String msg = String.format("UNLOCK FAILED: key=%s", lockKey); throw new IllegalStateException(msg, e); } }
执行解锁代码后,有时会出现以下报错,这是什么原因呢?
Caused by: java.lang.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread
比如下面这段代码,在获取锁成功之后,持有的时间是8秒,而如果你的锁内业务执行时间超过8秒后,锁会自动释放,锁自动释放后,而在你的finally里面又手动去释放锁,就导致了这个错误。
@Test public void testLock() { String key = "key"; try { // 获取锁,持有8秒后,自动释放 tryLock(key, 1000L, 8000L); TimeUnit.SECONDS.sleep(10); } catch (Exception e) { e.printStackTrace(); } finally { unlock(key); } }
解决办法
public void unlock(String lockKey) { try { RLock lock = redissonClient.getLock(lockKey); if (lock != null && lock.isHeldByCurrentThread()) { lock.unlock(); } } catch (Throwable e) { String msg = String.format("UNLOCK FAILED: key=%s", lockKey); throw new IllegalStateException(msg, e); } }
解锁时,增加lock.isHeldByCurrentThread()判断,意思是查询当前线程是否持有该锁,如果还持有,则释放,未持有,说明已释放。
关注公众号:臻大虾,分享更多java干货
你的支持是对我不断创作的极大鼓励,咱们下期见。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)