Medium java java-21

What is the difference between synchronized and ReentrantLock?

The 30 second answer

Both give mutual exclusion and the same memory visibility guarantees. Synchronized is simpler and always releases the lock when the block ends, even on an exception. ReentrantLock gives more control: try to lock with a timeout, wait in a way that can be interrupted, optional fairness, and multiple conditions. The cost is that I must unlock in a finally block myself.

private final ReentrantLock lock = new ReentrantLock();

void transfer() throws InterruptedException {
    if (lock.tryLock(500, TimeUnit.MILLISECONDS)) {
        try { /* critical section */ }
        finally { lock.unlock(); }
    } else {
        // back off instead of waiting forever
    }
}
synchronizedReentrantLock
Releaseautomaticmanual, in finally
Try / timeoutnotryLock(), tryLock(timeout)
Interruptible waitnolockInterruptibly()
Fairnessnonew ReentrantLock(true)
Conditionsone wait set (wait / notify)many Conditions (await / signal)

Both are reentrant: the owning thread can acquire the lock again. [Opinion] Default to synchronized; use ReentrantLock when you need its extra features. On Java 21 with virtual threads, also prefer ReentrantLock around long blocking calls to avoid pinning (fixed for synchronized in Java 24 by JEP 491).

Sources: ReentrantLock Javadoc, Lock Javadoc (memory synchronization), JLS 17.1 Synchronization, JEP 444: Virtual Threads

Sources (0)
See inline citations in the answer above.