ReentrantLock
void a() {
lock.lock(); //got intrinsic lock
System.out.println(Thread.currentThread().getName());
System.out.println("In A");
b(); // called method in synchronized block
Thread.sleep(2000); // sleeping current thread(avoided try catch for simplicity)
System.out.println("after calling method B()");
System.out.println(Thread.currentThread().getName());
lock.unlock(); // releasing intrinsic lock
}
void b() {
lock.lock();// getting intrinsic lock, no problem as calling thread already has intrinsic lock
System.out.println(Thread.currentThread().getName());
System.out.println("In B");
lock.unlock(); // intentionally releasing lock, so now there is no lock .
Thread.sleep(2000);
}
产生两个线程Thread-0和Thread-1都调用a()。
在()中,我得到内在锁定,而不是我调用b()。在b()中我也获得内在锁定,因此我将获得当前线程拥有的相同锁定。 现在我故意在b()中解锁,释放锁定,以便其他等待线程可以获得锁定,只是为了确保我甚至让当前线程休眠。当我的线程在b()中休眠2000毫秒而在一个()中休眠2000毫秒时,我期待其他线程通过获取释放的锁来运行a()。
但它根据我的输出没有发生
输出: -
Thread-0
In A
Thread-0
In B
after calling method B()
Thread-0
Thread-1
In A
Thread-1
In B
after calling method B()
Thread-1
答案 0 :(得分:3)
现在我故意在b()中解锁,释放锁定,以便其他等待的线程可以获得锁定
不,它没有完全释放它 - 它只是递减锁定计数。在致电unlock
之前,您已拨打lock
两次,因此保留计数为2.拨打unlock
后,保留计数为1,因此它仍然阻止其他线程获取锁定。基本上,您的代码有点像:
void a() {
synchronized (foo) {
b();
}
}
void b() {
synchronized(foo) {
// In here, the count is 2
}
// Now the count is still 1...
}
答案 1 :(得分:2)
了解锁类的名称是可重入锁定非常重要,这意味着同一个线程可以多次获取锁定,但必须释放相同的次数才能走出监视器。
在Java-8中引入了一个名为StampedLock
的其他锁类,它不是可重入的,并且会有不同的行为。