A synchronized
statement acquires a mutual-exclusion lock (§17.13) on behalf
of the executing thread, executes a block, then releases the lock. While the executing thread owns the lock, no other thread may acquire the lock.
SynchronizedStatement:
synchronized (
Expression)
Block
The type of Expression must be a reference type, or a compile-time error occurs.
A synchronized
statement is executed by first evaluating the Expression.
If evaluation of the Expression completes abruptly for some reason, then the synchronized
statement completes abruptly for the same reason.
Otherwise, if the value of the Expression is null
, a NullPointerException
is thrown.
Otherwise, let the non-null
value of the Expression be V. The executing thread locks the lock associated with V. Then the Block is executed. If execution of the Block completes normally, then the lock is unlocked and the synchronized
statement completes normally. If execution of the Block completes abruptly for any reason, then the lock is unlocked and the synchronized
statement then completes abruptly for the same reason.
Acquiring the lock associated with an object does not of itself prevent other threads from accessing fields of the object or invoking unsynchronized methods on the object. Other threads can also use synchronized
methods or the synchronized
statement in a conventional manner to achieve mutual exclusion.
The locks acquired by synchronized
statements are the same as the locks that are acquired implicitly by synchronized
methods; see §8.4.3.5. A single thread may hold a lock more than once. The example:
class Test { public static void main(String[] args) { Test t = new Test(); synchronized(t) { synchronized(t) { System.out.println("made it!"); } } } }
made it!
This example would deadlock if a single thread were not permitted to lock a lock more than once.