synchronized in detail
Know exactly which object a synchronized block locks, and which objects you must never lock on.
Open this lesson in the learning hubKey points
- Every object owns one monitor.
synchronizedmeans: hold that monitor, or wait outside until the owner leaves. - A synchronized instance method locks
this. A static one locks theClassobject. Those are two different locks. - A synchronized block lets you choose the monitor and keep the critical section short. Prefer it to locking a whole method.
- Monitors are reentrant. A thread already holding one can enter another block on the same object without blocking itself.
- Lock a
private final Object. Locking a String literal, a boxed Integer orthislets unrelated code lock you out. - Releasing a monitor publishes every write made inside it to the next thread that acquires it. Locking buys visibility too.
Example
public class Main {
static int shared = 0;
static final Object LOCK = new Object();
public static void main(String[] args) throws InterruptedException {
Counter c = new Counter();
Thread[] ts = new Thread[4];
for (int i = 0; i < ts.length; i++) {
ts[i] = new Thread(() -> {
for (int n = 0; n < 50_000; n++) {
c.bump(); // monitor = the Counter instance
synchronized (LOCK) { shared++; } // monitor = one private object
}
});
ts[i].start();
}
for (Thread t : ts) t.join();
System.out.println("instance monitor : " + c.value());
System.out.println("block monitor : " + shared);
System.out.println("reentrant call : " + c.bumpTwice());
System.out.println("class monitor : " + describe());
}
static synchronized String describe() { // static locks Main.class instead
return "static synchronized locks Main.class";
}
static class Counter {
private int value;
synchronized void bump() { value++; }
synchronized int value() { return value; }
synchronized int bumpTwice() { bump(); bump(); return value; } // reentrant
}
}
Know which object you are locking, and keep the block small.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Multithreading course, and every lesson in it is listed on the Multithreading contents page.