![](/img/trans.png)
[英]How is ReentrantLock fair if the same thread keeps acquiring the lock again and again?
[英]ReentrantLock lock and unlock by always the same thread
我正在尝试在多线程上实现可重入锁,但是由于某些原因,同一线程将解锁,然后再次锁定,从而导致始终使用同一线程来运行相同的操作。
下面的代码是如何产生线程的
IntStream.range(0,(NUMBER_OF_THREADS)).forEach(index ->{
boolean operation = (index % 2 == 0) ? true : false;
Thread t = new Thread(new Client(operation,this));
t.start();
});
这是线程的运行功能的工作方式
@Override
public void run() {
while(!Thread.interrupted()) {
System.out.println("Trying to acquire lock : " + main.getLock().tryLock()
+ " thread id " + Thread.currentThread().getName());
// if (main.getLock().tryLock()) {
try {
main.getLock().lock();
if(main.getLock().isHeldByCurrentThread()) {
System.out.println("Lock held by this thread " + main.getLock().isHeldByCurrentThread()
+ " thread id : " + Thread.currentThread().getName());
if (operation) {
main.getcAaccount().deposit(1);
} else {
main.getcAaccount().withdraw(2);
}
Thread.currentThread().sleep(3000);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("Thread id : " + Thread.currentThread().getName() + " unlocking");
main.getLock().unlock();//always have the unlock part here to ensure it unlock
}
}
它正确地打印出其他5个线程正在尝试获取该锁定并失败,然后线程ID ...正在解锁...并且即使该线程应该处于睡眠状态,该线程也会立即再次锁定。
在这种逻辑情况下,我是否有任何遗漏?
先感谢您。
重入要求每个锁定之后都需要进行随后的解锁。 例如,如果我调用lock.lock()
三次,则期望我也调用lock.unlock()
三次。 在此事件序列发生之前, ReentrantLock
不会认为自己已解锁。
您没有意识到的是lock.tryLock()
如果成功的话,其行为本质上类似于调用lock.lock()
。 因此,通过两次lock
,您还需要unlock
两次。 在您的代码示例中,您仅解锁一次,因此最初锁定的线程在技术上仍拥有该锁。
修复起来应该很简单,您可以从代码中删除第二个lock.lock()
,并且互斥仍然有效。 要么,或者如果您需要阻止锁定,则将lock.tryLock()
替换为lock.lock()
。
根据您的编辑,您解决了删除多余锁的问题,但是现在您遇到了计时问题。 您实际上并不需要tryLock
。 您可以用lock
替换它,因为如果已经持有了锁,则lock
调用将挂起线程并阻塞线程(最终在调用解锁时唤醒)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.