When you synchronize on an object your thread gains exclusive use of that object until synchronization ends or wait is called on the object.
Language support for synchronization: 1. Use the synchronized block: In a method you may: synchronized(object) { code here }
synchronized(SomeClass.class) { code here }
In the first case access to the instance variables/methods of the class are synchronized. In the second case access to the static methods/fields are synchronized.
2. Declare the method synchronized: public synchronized foo() { code here }
public static synchronized foo() { code here }
These two act just like synchronized(this) or synchronized(MyClass.class) (depending if the method is static or not).
In addition the Object class defines the wait, notify, notifyAll, and sleep methods. To execute any of these methods the object must be in a synchronized block (this can be in a calling method). The compiler will not check this, a runtime error will be thrown if this is not the case. The wait method temporaly releases the lock on the object. The notify/notifyAll method allows a previously waiting thread to continue to execute.
Also when executing the static block of a class: public class Foo { static { code here } }
A special lock is placed on the class, this lock is different from the synchronized lock, as no other thread may access the class until the static block is done.