可重入 tryLock() 在多线程环境中不锁定

Renentrant tryLock() not locking in multi threaded enviroment

这是关于重入锁中的tryLock()方法。我正在 运行ning 下面的示例代码。我知道这段代码会 运行 陷入死锁。

import java.util.concurrent.locks.ReentrantLock;
public class TestMain {
    public static void main(String[] args) {
        ReentrantLock rl=new ReentrantLock();
        S t1=new S(rl);
        S t2=new S(rl);
        Thread t=new Thread(t1);
        Thread u=new Thread(t2);
        t.start();
        u.start();
    }
}
class S extends Thread{
    ReentrantLock rl;
    S(ReentrantLock r){
        rl=r;
    }
    public void run(){
        System.out.println("Entry--");
        rl.tryLock();
        System.out.println("locked1 "+rl.getHoldCount()+" "+Thread.currentThread().getName());
        rl.lock();
        System.out.println("locked2 "+rl.getHoldCount()+" "+Thread.currentThread().getName());
        rl.unlock();
        System.out.println("unlocked "+rl.getHoldCount()+" "+Thread.currentThread().getName());
    }
}

但是我的问题是,为什么 rl.tryLock() 语句之后的语句对于第二个线程也是 运行ning。输出为

Entry--
Entry--
locked1 0 Thread-3
locked1 1 Thread-2
locked2 2 Thread-2
unlocked 1 Thread-2

我认为这行不应该被打印出来

"locked2 2 Thread-2"

lock 一样,tryLock 也必须与 unlock IF 配对 returns true。使用 tryLock 时,您必须检查 return 值并在它被锁定时解锁,否则它将永远无法完全解锁。

打印时会出现以下序列:[注意这是一个可能的序列,5 到 8 之间可以重新排列,因为涉及多个线程,它仍然是正确的]

  1. [线程 2]System.out.println("Entry--");
  2. [线程 3]System.out.println("Entry--");
  3. [Thread-2] rl.tryLock(); [r1 现在锁定到 Thread-2,count=1]
  4. [Thread-3] rl.tryLock(); [r1 已锁定,returns false]
  5. [Thread-3] System.out.println("locked1 "+rl.getHoldCount()+" "+Thread.currentThread().getName()); [r1 未保留,因此计数为 0]
  6. [Thread-2] System.out.println("locked1 "+rl.getHoldCount()+" "+Thread.currentThread().getName()); [r1 举行,count=1]
  7. [Thread-3] rl.lock(); [r1 已锁定,阻塞]
  8. [Thread-2] r1.lock(); [r1 举行,count=2]
  9. [线程 2]System.out.println("locked2 "+rl.getHoldCount()+" "+Thread.currentThread().getName());
  10. [Thread-2] rl.unlock(); [r1 举行,count=1]
  11. [线程 2]System.out.println("unlocked "+rl.getHoldCount()+" "+Thread.currentThread().getName());

打印行 "locked2 2 Thread-2" 是因为可重入锁可以多次锁定 如果被持有者锁定。所以 tryLocklock 都成功了,但是你只解锁了其中一个,所以另一个线程永远阻塞。