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);
}
Two threads are spawned Thread- 0 and Thread-1 both are calling a().
In a(), I am getting intrinsic lock and than I'm calling b(). In b() also I'm getting intrinsic lock so I'll get the same lock possessed by current thread. Now I'm intentionally unlocking in b() which releases the lock so that other waiting thread could get the lock, just to make sure I even made current thread sleep . While my thread is sleeping in b() for 2000 ms and than in a() for 2000 ms I was expecting other thread would run a() by getting the released lock.
But its not happening as per my output
Output :-
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
Now I'm intentionally unlocking in b() which releases the lock so that other waiting thread could get the lock
No, it doesn't fully release it - it just decrements the lock count. Before you call unlock
, you've called lock
twice, so the hold count is 2. After you call unlock
, the hold count is 1, so it's still preventing the other thread from acquiring the lock. Basically, your code is a bit like having:
void a() {
synchronized (foo) {
b();
}
}
void b() {
synchronized(foo) {
// In here, the count is 2
}
// Now the count is still 1...
}
See more on this question at Stackoverflow