为什么以下代码导致死锁
我有以下课程
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(); } } }
和洛克class
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(); } }
为什么运行此代码会导致死锁。
lock1被锁定两次:一次在lockFirst
,一次在unlockFirst
( lock1.tryLock()
),但在unlockFirst
只解锁一次。
ReentrantLock有保留计数。 请参阅ReentrantLock 。 如果你调用tryLock,即使它已经被当前线程保持,它仍然会增加保持计数。 所以,你增加两次,但只减少一次。
锁定lock1
,你永远无法完全解锁它 。 如果线程在调用unlockFirst()
时保持lock1
,则在函数返回时它仍将保持lock1
。
如果你调用lock1.lock()
后跟一个成功的lock1.tryLock()
,你需要调用lock1.unlock()
两次才能完全释放锁。 你的代码没有这样做,因此死锁。
您在所有线程中共享静态Locker。
在某些时候,线程将尝试tryLock(),而锁已被另一个线程持有。
编辑:不正确,忽略。