Card 05/ 09
All 9 cards
ConceptDifficulty: Advanced1 min
Re-entering a Lock You Are Already Holding
A synchronized method calls another synchronized method on the same object. The second one needs a lock the first one is holding, and the thread does not deadlock against itself.
class Account {
synchronized void withdraw(long amount) {
if (amount <= balance()) { pence -= amount; }
}
synchronized long balance() { return pence; }
}Java's locks are reentrant: they are held by a thread rather than by a block, and a thread that already holds one may acquire it again. The lock keeps a count, and it is released only when that count returns to zero.
Without reentrancy, a class could not call its own synchronized methods, and a subclass overriding a synchronized method could not call super. Both would deadlock instantly against a lock the same thread was holding.
So keep synchronized regions short and keep foreign calls out of them. Gather what you need under the lock, release it, and then call whatever needs calling.