Difference Between synchronized and ReentrantLock?

synchronized and ReentrantLock are both Java locking mechanisms for mutual exclusion, but ReentrantLock is a more flexible, explicit API that offers capabilities the simpler synchronized keyword doesn't provide.

Key Points: • synchronized locks and unlocks automatically at block/method boundaries, even across exceptions, with no chance of forgetting to release the lock. • ReentrantLock requires explicit lock() and unlock() calls, typically wrapped in a try/finally to guarantee release. • ReentrantLock supports tryLock() with optional timeouts, letting a thread give up instead of waiting forever for a contended lock. • ReentrantLock supports lockInterruptibly(), allowing a thread blocked on a lock to respond to interruption. • ReentrantLock supports a fairness policy (constructor flag) and multiple Condition objects per lock, enabling more nuanced wait/notify style coordination than a single monitor allows.

Example: A connection pool that wants to give up waiting for a lock after 500ms rather than blocking indefinitely would use lock.tryLock(500, TimeUnit.MILLISECONDS), something synchronized simply cannot express.

Code Example:

private final ReentrantLock lock = new ReentrantLock();

public void update() {
    lock.lock();
    try {
        // critical section
    } finally {
        lock.unlock();
    }
}

Interview Tip: A concise interview answer is:

"synchronized is simpler and safer by default since the JVM handles lock release automatically, even on exceptions. ReentrantLock trades that simplicity for more control — tryLock with timeouts, interruptible locking, fairness policies, and multiple conditions per lock — which matters for more advanced concurrency scenarios."