The Java language specification defines the value of a synchronized statement as follows:
OperatorA synchronized obtains a mutual exclusion lock (§17.1) on behalf of the executing thread, executes the block, and then releases the lock. While the executing thread holds the lock, no other thread can get the lock.
SynchronizedStatement:` synchronized ( Expression ) Block`
The type of the expression must be a reference type, or a compile-time error occurs.
The synchronized statement is executed by evaluating the expression first.
If for any reason the Expression evaluation terminates unexpectedly, then the synchronized statement terminates unexpectedly for the same reason.
Otherwise, if Expression is null, a NullPointerException is thrown.
Otherwise, let the non-empty value of the expression be V. The execution thread blocks the lock associated with V. Then the Block is executed. If the execution of the Block completes normally, the lock is unlocked, and the synchronized statement completes normally. If the execution of the Block terminates abruptly for any reason, the lock is unlocked, and the synchronized statement terminates abruptly for the same reason.
Acquiring a lock associated with an object does not in itself prevent other threads from accessing the fields of the object or calling unsynchronized methods on the object. Other threads may also use synchronized methods or a synchronized statement in the usual way to achieve mutual exclusion.
That is, in your example
synchronized(this) { listOne.add(something); }
the synchronized block processes the object referenced by listOne any special way, other threads can work with it at their discretion. However, it ensures that no other thread can simultaneously enter a synchronized block for the object referenced by this . Therefore, if all the code working with listOne is in synchronized blocks for the same object, no more than one thread can work with listOne at any given time.
Also note that the locked object does not receive special protection from the simultaneous access of its state, so the code
void increment() { synchronized (this) { this.counter = this.counter + 1; } } void reset() { this.counter = 0; }
it doesn’t synchronize properly, since the second thread can reset while the first thread has read, but not yet written, counter , as a result of which reset is overwritten.