Card 06/ 09
All 9 cards
ComparisonDifficulty: Advanced1 min
synchronized Against ReentrantLock
ReentrantLock does what synchronized does, with a method call instead of a keyword, and adds four things the keyword cannot express.
| Compared on | synchronized | ReentrantLock |
|---|---|---|
| Released automatically | Yes, on every exit from the block | No — needs a finally |
| Give up after a timeout | No | tryLock(5, SECONDS) |
| Give up immediately if held | No | tryLock() |
| Interruptible while waiting | No | lockInterruptibly() |
| Acquire in one method, release in another | No | Yes |
| Fairness, first come first served | No | Optional, at a cost |
private final ReentrantLock lock = new ReentrantLock();
void withdraw(long amount) {
lock.lock();
try {
if (amount <= pence) { pence -= amount; }
} finally {
lock.unlock();
}
}The finally is not optional and not a style choice. Without it, an exception inside the block leaves the lock held forever and every other thread waits on it for the life of the process.
The decision rule. Use synchronized by default — it cannot be left unreleased, and it is shorter. Reach for ReentrantLock when you need one of the four rows the keyword cannot do, and most often that row is the timeout.