Reputation: 164
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
Upvotes: 1
Views: 1151
Reputation: 1607
It is very important to understand that the name of the lock class is ReentrantLock, which means that the same Thread can acquire the lock multiple times, but has to release the same number of times to come out of monitor.
There is other lock class introduced in Java-8 called StampedLock
which is not Re-entrant and will have a different behavior.
Upvotes: 3
Reputation: 1503479
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...
}
Upvotes: 4