So , a reentrant lock increments the count by one if the current thread acquires the lock again. what i am unable to understand is why and how that helps or benefits us?
-
Welcome to StackOverflow! It looks like your question is not really about Java, because reentrant locks are a concept that extends well beyond a single language. On that basis it might already have an answer [here](https://stackoverflow.com/questions/1312259/what-is-the-re-entrant-lock-and-concept-in-general). – cooperised Aug 30 '18 at 13:06
-
Also does the [JavaDoc for ReentrantLock](https://docs.oracle.com/javase/10/docs/api/java/util/concurrent/locks/ReentrantLock.html) give some explanations. – LuCio Aug 30 '18 at 13:10
-
According to the JavaDoc (see my comment above) an `ReentrantLock` does have the "_same basic behavior and semantics as the implicit monitor lock accessed using synchronized methods and statements_" Here is a simple [example](https://stackoverflow.com/a/51617275/2838289) to see the reentrance in action using the keyword `synchronized`. – LuCio Aug 30 '18 at 13:40
3 Answers
The reason, that a reentrant lock is doing this, is to not lock the same Thread again, that has already acquired this lock.
For example: Let's say you have Thread A that is acquiring your Reentrant Lock A. Than Thread B tries to acquire the Lock A, which will result in Thread B getting blocked (more about the Thread states can be found here). Now, Thread A is trying to (again) acquire the Lock A.
Because the Reentrant lock is now highering its count, Thread A is not getting blocked. Thread A still has access over the Lock and can continue (the locks stores the informations about the depth). If he (sooner or later) releases the Lock, the count will be lowered again, to check if Thread A still need the Lock or not. If the count gets to 0, meaning Thread A has released for every time he has acquired, Thread B will get the access over the Lock.
Without reentrancy, you now would have a deadlock. Why? Because Thread A has the lock and would wait to get it again.
Concurrency can be realy complicated, reentrancy helps (just a bit) reducing this complexity.

- 1,092
- 12
- 25
-
This makes some pretty misleading logical leaps and only briefly/incidentally mentions the real problem that counter-based locking solves. – Mark Adelsberger Aug 30 '18 at 13:32
-
@MarkAdelsberger I have provided an example that goes through an example with sources too look stuff up. Why do i only mention the real problem just briefly/incidentally? The Question was not about "what is a deadlock", but about why the counter is needed. – Thorben Kuck Aug 30 '18 at 13:37
-
The counter doesn't solve deadlocks. It solves premature release of the lock. That's my point. – Mark Adelsberger Aug 30 '18 at 13:40
-
@MarkAdelsberger you are right, but deadlocks are also prevented with this. If you have the access over a lock that is not reentrant and acquire it again, the result will be a deadlock. – Thorben Kuck Aug 30 '18 at 13:42
-
The counter does not prevent deadlocks. It would be perfectly possible to allow the thread that holds a lock to pass through additional lock calls without keeping a counter. – Mark Adelsberger Aug 30 '18 at 13:43
-
(To further clarify my point: The counter *which is what the question explicitly asks about* does not prevent deadlocks. It would be perfectly possible to allow the thread that holds a lock to pass through additional lock calls without keeping a counter. As I said, your answer makes misleading logical leaps by saying "without a counter this would happen" when you mean "of the two options Java offers, if you use the one without a counter this will happen".) – Mark Adelsberger Aug 30 '18 at 13:49
-
@MarkAdelsberger I understand your point and i know, that i could have elaborated a bit more on that. However, reentrancy also prevents deadlocks because of the counter. You can see this, if you try to acquire 2 times a Semaphore with 1 permit. Those are not reentrant and they will result in a deadlock. I simply wanted to provide the sources to let him figure stuff out on his own. On the same hand, the assumption "without a counter this would not happen" is also false. That's why i stated both things. – Thorben Kuck Aug 30 '18 at 14:00
This helps for the unusual situation when you want to call another method that also requires a lock.
ReentrantLock lock = new ReentrantLock();
public void doSomething() {
lock.lock();
try {
// Something.
} finally {
lock.unlock();
}
}
public void somethingElse () {
lock.lock();
try {
// Something else.
// We can now call another locking method without risking my lock being released.
doSomething();
} finally {
lock.unlock();
}
}
Here public can call doSomething
and it will acquire the lock, do it's thing and then release the lock when unlock
is called.
However, when somethingElse
is called and it calls doSomething
it just increases the lock count. When doSomething
unlocks it does not release the lock, it merely counts the lock-count down, leaving the final unlock in somethingElse
to release the lock.

- 64,482
- 16
- 119
- 213
-
Can't we have other lock to protect doSomething() ? Is it for performance issue? – PeerNet Mar 09 '19 at 19:00
-
-
I want to clear things in my head. If we don't have ReentrantLock, we can use other Lock object, right? I want to understand the need of ReentrantLock, what does it provide us? Not to create another lock and save some space? – PeerNet Mar 10 '19 at 11:19
The point of incrementing a count for the lock is to keep track of how many times the thread acquired the lock, so that the lock won't actually be released until the thread indicates readiness to release the lock the same number of times.
The assumption is that commands for locking will be matched with commands for releasing the lock.
Say my code enters Code Section A, which requires the lock.
Then without exiting Code Section A, it enters Code Section B which also requires the same lock. As you note we have the lock, so we needn't block.
But we'll leave Section B, and Section B is written to release the lock when we exit it. (Otherwise code that reaches Section B without already having the lock would never release the lock.)
We're still in Section A, though, so we don't want to really give up the lock yet, or another thread could take it while we're in Section A.
So when we entered Section B we incremented the lock count, which means when we exit Section B we can reduce the count by one and, seeing that it's not back to 0, not release it.
Then when Section A again releases the lock, the count falls back to 0 and that is when we really let the lock go.

- 42,148
- 4
- 35
- 52