Java › Concurrency & Threads
How does java.util.concurrent's ReentrantLock differ from the synchronized keyword, and what additional capabilities does it provide (tryLock, fairness, interruptible locking)?
AdvancedAnswer
ReentrantLock provides everything synchronized offers (mutual exclusion, reentrancy -- a thread already holding the lock can re-acquire it without deadlocking itself) plus additional capabilities unavailable with synchronized: tryLock() (attempt to acquire without blocking indefinitely, optionally with a timeout, avoiding a thread getting stuck waiting forever), lockInterruptibly() (allows a blocked thread to be interrupted rather than waiting unconditionally), fairness (an optional constructor parameter approximating first-come-first-served lock acquisition order, reducing thread starvation at some throughput cost), and the ability to have multiple associated Condition objects for more granular wait/notify-style coordination than a single object's intrinsic wait()/notify().
private final ReentrantLock lock = new ReentrantLock();
public boolean tryUpdate() {
if (lock.tryLock()) { // non-blocking attempt, unlike synchronized which would wait indefinitely
try {
// critical section
return true;
} finally {
lock.unlock(); // MUST be in finally -- unlike synchronized, unlock isn't automatic
}
}
return false; // couldn't acquire the lock, caller can decide to retry, skip, or fail fast
}Real-world example A resource-management system uses ReentrantLock's tryLock() with a timeout to attempt acquiring a lock for a limited period before giving up and returning an error to the caller, avoiding the indefinite blocking that a plain synchronized block would impose if the lock happened to be held for an unexpectedly long time.