我有以下课程
public class LockTester implements Runnable{
private static Locker locker = new Locker();
public static void main(String[] args){
for(int i=0;i<10;i++){
Thread t = new Thread(new LockTester());
t.start();
}
}
public void run(){
for(int i=0;i<1000;i++){
locker.unlockFirst();//note unlocking here
locker.lockFirst();
locker.lockSecond();
locker.unlockSecond();
locker.unlockFirst();
}
}
}
和Locker类
public class Locker{
private Lock lock1 = new ReentrantLock();
private Lock lock2 = new ReentrantLock();
public void lockFirst(){
lock1.lock();
}
public void lockSecond(){
lock2.lock();
}
public void unlockFirst(){
if(lock1.tryLock()){//note change
lock1.unlock();
}
}
public void unlockSecond(){
lock2.unlock();
}
}
为什么运行此代码会导致死锁。
答案 0 :(得分:9)
lock1被锁定两次:一次在lockFirst
,一次在unlockFirst
(lock1.tryLock()
),但只在unlockFirst
解锁一次。
ReentrantLock有暂停计数。见ReentrantLock。如果你调用tryLock,即使它已经被当前线程保持,它仍然会增加保持计数。所以,你将它递增两次,但只递减一次。
答案 1 :(得分:2)
锁定lock1
后,您永远无法完全解锁。如果线程在调用lock1
时保持unlockFirst()
,则在函数返回时它仍会保留lock1
。
如果您致电lock1.lock()
,然后成功lock1.tryLock()
,则需要致电lock1.unlock()
两次以完全解除锁定。你的代码没有这样做,因此陷入僵局。
答案 2 :(得分:-2)
您在所有线程中共享静态Locker。
在某个时刻线程将尝试tryLock(),而锁已被另一个线程持有。
编辑:不正确,忽略。