A thread entering a synchronized instance method acquires the lock associated with
acquiresthelockassociatedwiththeclass's Class object.Finally,athreadenteringa
synchronized block acquires the lock associated with the block's controlling object.
Tip Thread declaresa static boolean holdsLock(Object o) method
that returns true when the calling thread holds the monitor lock on object o . You
will find this method handy in assertion statements, such as assert
The need for synchronization is often subtle. For example, Listing 4-23 's ID utility
classdeclaresa getNextID() methodthatreturnsaunique long -basedID,perhaps
to be used when generating unique filenames. Although you might not think so, this
method can cause data corruption and return duplicate values.
Listing 4-23. A utility class for returning unique IDs
private static long nextID = 0;
static long getNextID()
There are two lack-of-synchronization problems with getNextID() . Because
to nextID is not atomic: the scheduler could interrupt a thread that has only updated
half of nextID , which corrupts the contents of this variable.
Note Variables of type long and double are subject to corruption when being
with variables of type boolean , byte , char , float , int , or short ; each type
occupies 32 bits or less.
Assumethatmultiplethreadscall getNextID() .Becausepostincrement( ++ )reads
and writes the nextID field in two steps, multiple threads might retrieve the same
value. For example, thread A executes ++ , reading nextID but not incrementing its