The <code>synchronized</code> Keyword in Java

synchronized is Java's built-in locking mechanism. It guarantees that at most one thread at a time executes the synchronised code on a given monitor, and that writes before releasing the lock are visible to the next thread that acquires it.

Method-level

public class Counter {
    private int count;

    public synchronized void increment() {        // locks on `this`
        count++;
    }
    public static synchronized void reset() {      // locks on the Class object
        ...
    }
}

Block-level β€” finer-grained

private final Object lock = new Object();
private int count;

public void increment() {
    synchronized (lock) {
        count++;
    }
}

Prefer a private lock object over synchronized(this). It prevents outside code from accidentally (or maliciously) acquiring your class's lock.

Reentrancy

A thread that already holds a monitor can re-enter it. This lets a synchronised method call another one on the same object without deadlocking.

Memory visibility β€” the happens-before guarantee

Everything a thread writes before releasing a lock is visible to the next thread that acquires the same lock. This is what actually makes synchronized useful β€” without it, reads might see stale values from CPU caches.

When to reach for java.util.concurrent instead

  • ReentrantLock β€” interruptible waits, tryLock with timeout, multiple conditions.
  • AtomicInteger, AtomicReference, LongAdder β€” lock-free counters.
  • ConcurrentHashMap β€” replaces synchronized Map.
  • CopyOnWriteArrayList β€” read-heavy list.

Modern Java often replaces synchronized with these β€” better performance under contention, clearer intent.

Common mistakes

  • Locking on a public or mutable object β€” anyone can lock on this or a public field, causing deadlocks. Use a private final lock.
  • Forgetting that String intern or Integer cache are shared β€” synchronized("foo") can deadlock across unrelated code.
  • Synchronising on mutable fields β€” if the field is reassigned, different threads lock on different objects.
  • Over-synchronising β€” a long critical section serialises all threads. Keep them minimal.

Related

Pillar: Java keywords. See also volatile.