practice, this mechanism produces race conditions between these deadlocks and
resume() , that render this group of methods unusable.
This method was never implemented—it would have suffered from the same race
condition issues as suspend() if it had been.
All of these deprecated methods should always be avoided. Instead, a set of safe
alternative patterns that achieve the same intended aims as the preceding methods
have been developed. A good example of one of these patterns is the run-until-
shutdown pattern that we have already met.
Working with Threads
In order to work effectively with multithreaded code, it's important to have the basic
facts about monitors and locks at your command. This checklist contains the main
facts that you should know:
• Synchronization is about protecting object state and memory, not code.
• Synchronization is a cooperative mechanism between threads. One bug can
break the cooperative model and have far-reaching consequences.
• Acquiring a monitor only prevents other threads from acquiring the monitor—
it does not protect the object.
• Unsynchronized methods can see (and modify) inconsistent state, even while
the object's monitor is locked.
• Locking an Object doesn't lock the individual objects.
• Primitives are not mutable, so they can't (and don't need to) be locked.
• synchronized can't appear on a method declaration in an interface.
• Inner classes are just syntactic sugar, so locks on inner classes have no effect on
the enclosing class (and vice versa).
• Java's locks are reentrant . This means that if a thread holding a monitor
encounters a synchronized block for the same monitor, it can enter the block. 2
We've also seen that threads can be asked to sleep for a period of time. It is also use‐
ful to go to sleep for an unspecified amount of time, and wait until a condition is
met. In Java, this is handled by the wait() and notify() methods, that are present
on Object .
Just as every Java object has a lock associated with it, every object maintains a list of
waiting threads. When a thread calls the wait() method of an object, any locks the
thread holds are temporarily released, and the thread is added to the list of waiting
2 Outside of Java, not all implementations of locks have this property.