Javed Solkar
Javed Solkar

Reputation: 164

ReentrantLock - unlocking in called method

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

Answers (2)

Nitin Dandriyal
Nitin Dandriyal

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

Jon Skeet
Jon Skeet

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

Related Questions