Java 可重入锁定始终通过同一线程锁定和解锁
我试图在多线程上实现可重入锁,但由于某些原因,同一线程解锁,然后再次锁定,导致始终运行同一线程,因此执行相同的操作 下面是如何生成线程的代码Java 可重入锁定始终通过同一线程锁定和解锁,java,multithreading,reentrantlock,Java,Multithreading,Reentrantlock,我试图在多线程上实现可重入锁,但由于某些原因,同一线程解锁,然后再次锁定,导致始终运行同一线程,因此执行相同的操作 下面是如何生成线程的代码 IntStream.range(0,(NUMBER_OF_THREADS)).forEach(index ->{ boolean operation = (index % 2 == 0) ? true : false; Thread t = new Thread(new Client(operation
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();
});
下面是线程的run函数是如何工作的
@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
ing,您还需要两次unlock
。在代码示例中,您只解锁一次,因此最初锁定的线程在技术上仍然拥有锁
修复它应该很简单,您可以从代码中删除第二个lock.lock()
,互斥应该仍然有效。或者,如果需要锁定阻塞,则将lock.tryLock()
替换为lock.lock()
根据您的编辑,您解决了一个删除额外锁的问题,但现在您遇到了时间问题。您实际上不需要
tryLock
。您可以将其替换为lock
,因为lock
调用将挂起线程并在锁已被持有时阻塞(最终在调用解锁时唤醒)。您的目标是什么?您想实现什么?当您已经通过tryLock()
获得锁时,为什么要调用lock()
?阻止并发,其中一个线程存放,另一个线程绘制,但顺序并不重要。我只是不明白为什么同一个线程解锁,然后在它应该处于休眠状态时获得锁。我已经按照你说的做了,但仍然存在相同的问题。我会用你建议的补丁编辑一个截图。好的,那么你就遇到了时间问题。请考虑我的第二点:用<代码>锁定< /代码>替换<代码> TyyLoo< /Cord>。无需睡眠
,因为线程将被阻塞在lock()
上。我删除了if(lock.tryLock()),现在只有同一个线程自己工作。奇怪的东西。我的意思是其他5个线程没有打印任何获取锁的尝试。我将为您发布更新的代码,您将tryLock替换为lock.lock()
?哦,我的天啊,就像我常说的那样,是简单而愚蠢的事情破坏了复杂的东西。再次感谢你。就像一个符咒,不同的线程现在得到锁,循环在存款和取款之间以任意方式进行(无论哪个线程得到锁)。再次感谢您抽出时间。我投了赞成票,并接受了答案。