The Java platform keeps track of a special token, called a monitor , for every object
that it ever creates. These monitors (also called locks ) are used by synchronized to
indicate that the following code could temporarily render the object inconsistent.
The sequence of events for a synchronized block or method is:
1. Thread needs to modify an object and may make it briefly inconsistent as an
2. Thread acquires the monitor, indicating it requires temporary exclusive access
to the object
3. Thread modifies the object, leaving it in a consistent, legal state when done
4. Thread releases the monitor
If another thread attempts to acquire the lock while the object is being modified,
then the attempt to acquire the lock blocks, until the holding thread releases the
Note that you do not have to use the synchronized statement unless your program
creates multiple threads that share data. If only one thread ever accesses a data
structure, there is no need to protect it with synchronized .
One point which is of critical importance—acquiring the monitor does not prevent
access to the object. It only prevents any other thread from claiming the lock. Cor‐
rect concurrently safe code requires developers to ensure that all accesses that might
modify or read potentially inconsistent state acquire the object monitor before oper‐
ating on, or reading that state.
Put another way, if a synchronized method is working on an object and has placed
it into an illegal state, and another method (which is not synchronized) reads from
the object, it can still see the inconsistent state.
Synchronization is a cooperative mechanism for protecting
state and it is very fragile as a result. A single bug (such as
missing a single synchronized keyword from a method it's
required on) can have catastrophic results for the safety of the
system as a whole.
The reason we use the word synchronized as the keyword for “requires temporary
exclusive access” is that in addition to acquiring the monitor, the JVM also rereads
the current state of the object from main memory when the block is entered. Simi‐
larly, when the synchronized block or method is exited, the JVM flushes any modi‐
fied state of the object back to main memory.
Without synchronization, different CPU cores in the system may not see the same
view of memory, and memory inconsistencies can damage the state of a running
program, as we saw in our ATM example.