Card 04/ 09

GotchaDifficulty: Intermediate1 min

Why a static synchronized Method Does Not Lock the Instance

A class where every method is synchronized and one of them is static. Two threads run through it at the same time, and the shared field is corrupted anyway.

java
class Registry {
    private static int total;
    private int localTotal;

    static synchronized void addToTotal(int n) { total += n; }

    synchronized void addToLocal(int n) { localTotal += n; }
}

The two methods lock different things. Line 7 locks the instance it was called on. Line 5 has no instance — it is static — so it locks the Registry.class object instead.

What each form of synchronized locks
WrittenLocks
synchronized void m()this, the instance it was called on
static synchronized void m()The class object, shared by every instance
synchronized (obj) { }Whatever obj is

Guard state with the lock that matches its scope: a static field with the class lock, an instance field with the instance lock. Better still, give each piece of shared state a private lock object of its own, so the pairing is written down rather than implied.

java
private static final Object TOTAL_LOCK = new Object();
private final Object localLock = new Object();