Renentrant tryLock()没有锁定多线程环境

时间:2017-09-06 19:15:23

标签: java reentrantlock

这是关于重入锁定的tryLock()方法。我正在运行以下示例代码。我知道这段代码会陷入僵局。

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()语句之后的语句也在为第二个线程运行。输出即将到来

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

我认为这行不应该打印

"locked2 2 Thread-2"

1 个答案:

答案 0 :(得分:0)

lock一样,tryLock也必须与unlock IF配对,并返回true。当使用tryLock时,您必须检查返回值并解锁它是否被锁定,否则它将永远不会被完全解锁。

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

  1. [话题2] System.out.println("Entry--");
  2. [Thread-3] System.out.println("Entry--");
  3. [Thread-2] rl.tryLock(); [r1现已锁定至Thread-2,count = 1]
  4. [Thread-3] rl.tryLock(); [r1已锁定,返回false]
  5. [Thread-3] System.out.println("locked1 "+rl.getHoldCount()+" "+Thread.currentThread().getName()); [r1未被保留,count因此为0]
  6. [Thread-2] System.out.println("locked1 "+rl.getHoldCount()+" "+Thread.currentThread().getName()); [r1 hold,count = 1]
  7. [Thread-3] rl.lock(); [r1已锁定,阻止]
  8. [Thread-2] r1.lock(); [r1 hold,count = 2]
  9. [话题2] System.out.println("locked2 "+rl.getHoldCount()+" "+Thread.currentThread().getName());
  10. [Thread-2] rl.unlock(); [r1 hold,count = 1]
  11. [话题2] System.out.println("unlocked "+rl.getHoldCount()+" "+Thread.currentThread().getName());
  12. 打印行"locked2 2 Thread-2",因为如果持有者锁定,可以多次锁定重入锁。所以tryLocklock都成功,但你只解锁其中一个,所以其他线程永远阻止。