可重入 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 之间可以重新排列,因为涉及多个线程,它仍然是正确的]
- [线程 2]
System.out.println("Entry--");
- [线程 3]
System.out.println("Entry--");
- [Thread-2]
rl.tryLock();
[r1 现在锁定到 Thread-2,count=1]
- [Thread-3]
rl.tryLock();
[r1 已锁定,returns false]
- [Thread-3]
System.out.println("locked1 "+rl.getHoldCount()+" "+Thread.currentThread().getName());
[r1 未保留,因此计数为 0]
- [Thread-2]
System.out.println("locked1 "+rl.getHoldCount()+" "+Thread.currentThread().getName());
[r1 举行,count=1]
- [Thread-3]
rl.lock();
[r1 已锁定,阻塞]
- [Thread-2]
r1.lock();
[r1 举行,count=2]
- [线程 2]
System.out.println("locked2 "+rl.getHoldCount()+" "+Thread.currentThread().getName());
- [Thread-2]
rl.unlock();
[r1 举行,count=1]
- [线程 2]
System.out.println("unlocked "+rl.getHoldCount()+" "+Thread.currentThread().getName());
打印行 "locked2 2 Thread-2"
是因为可重入锁可以多次锁定 如果被持有者锁定。所以 tryLock
和 lock
都成功了,但是你只解锁了其中一个,所以另一个线程永远阻塞。
这是关于重入锁中的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 之间可以重新排列,因为涉及多个线程,它仍然是正确的]
- [线程 2]
System.out.println("Entry--");
- [线程 3]
System.out.println("Entry--");
- [Thread-2]
rl.tryLock();
[r1 现在锁定到 Thread-2,count=1] - [Thread-3]
rl.tryLock();
[r1 已锁定,returns false] - [Thread-3]
System.out.println("locked1 "+rl.getHoldCount()+" "+Thread.currentThread().getName());
[r1 未保留,因此计数为 0] - [Thread-2]
System.out.println("locked1 "+rl.getHoldCount()+" "+Thread.currentThread().getName());
[r1 举行,count=1] - [Thread-3]
rl.lock();
[r1 已锁定,阻塞] - [Thread-2]
r1.lock();
[r1 举行,count=2] - [线程 2]
System.out.println("locked2 "+rl.getHoldCount()+" "+Thread.currentThread().getName());
- [Thread-2]
rl.unlock();
[r1 举行,count=1] - [线程 2]
System.out.println("unlocked "+rl.getHoldCount()+" "+Thread.currentThread().getName());
打印行 "locked2 2 Thread-2"
是因为可重入锁可以多次锁定 如果被持有者锁定。所以 tryLock
和 lock
都成功了,但是你只解锁了其中一个,所以另一个线程永远阻塞。