Card 04/ 09

GotchaDifficulty: Intermediate1 min

static synchronized Locks the Class, Not the Instance

Every method is synchronized, one is static, and the shared state is corrupted anyway.

A static synchronized method locks the class object, Registry.class, while an ordinary synchronized method locks the instance it was called on. They are two different locks, so a static and a non-static synchronized method do not keep threads apart from each other.

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 state 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; }
}

Line 7 locks the instance it was called on. Line 5 has no instance, because 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();