Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reentrant Locking in Java

I was studying reentrant locking in Java. Need certain clarification on this concept that how actually it works. What all I understand for below snippet :

class Test{
    public synchronized a(){   
       some code;
      b();
       some code;
    }
    public synchronized b(){    
       some code;
    }

}

Above code has this scenario of reentrant lock issue.

What I understand here is, suppose we had Two Threads: T1 and T2 in application executing on Test shared object.

Whoever T1 or T2 acquires lock acquire on both a() and b(). Let say T1 first and executing a(). While execution of a() control reaches to b(); call. Now in that case T1 expecting a new Lock for this b(), or since it already had lock over b() so locking is skipped.

Need help with detailed explanation of this behavior along with issue in above code . Also how reentrant locking mechanism will help here along with snippet and detailed explanation for that as well.

like image 430
Neeraj Avatar asked Jan 27 '23 05:01

Neeraj


2 Answers

A reentrant lock is one that allows a thread to acquire the lock again (many times) when it already holds the lock.

For example, if thread T1 calls a() on an object, the a() method acquires the lock on the object, and starts executing the body. When the body of a calls b(), the b() call "reentrantly" acquires the same lock. When the b() call returns, the a() call is still holding the lock. The lock is only released when the a() call returns.

(Hypothetically, if Java primitive locks were not reentrant, then the sequence T1 calls a() which then calls b() would probably either deadlock, or throw an exception ...)

Reentrant locks are typically implemented with a reference count which tells the locking implementation how deep the reentrancy is.

See also: https://stackoverflow.com/a/16504266/139985

like image 181
Stephen C Avatar answered Jan 29 '23 19:01

Stephen C


If the lock wasn't re-entrant, the thread wouldn't be able to call b() while holding the lock it acquired when entering a().

When a() is called, and it call b() you need a lock which is reentrant or the thread will live lock itself try to acquire the lock a second time. Instead of trying to get the lock again, it instead recognises it already has a lock increments a counter so that when b() exists, it doesn't release the lock but instead decrements the counter.

like image 22
Peter Lawrey Avatar answered Jan 29 '23 18:01

Peter Lawrey