To synchronize threads, the Java programming language uses monitors, which are a high-level mechanism for allowing only one thread at a time to execute a region of code protected by the monitor.
The behavior of monitors is explained in terms of locks; there is a lock associated with each object.
The methods wait, notify, and notifyAll of classObject support an efficient transfer of control from one thread to another.
A thread can suspend itself using wait until such time as another thread awakens it using notify.
Each thread has a working memory, in which it may keep copies of the values of variables from the main memory that is shared between all threads.
To access a shared variable, a thread usually first obtains a lock and flushes its working memory. This guarantees that shared values will thereafter be loaded from the shared main memory to the threads working memory.
When a thread unlocks a lock it guarantees the values it holds in its working memory will be written back to the main memory.
Every thread has a working memory in which it keeps its own working copy of variables that it must use or assign. As the thread executes a program, it operates on these working copies. The main memory contains the master copy of every variable.
The main memory also contains locks; there is one lock associated with each object. Threads may compete to acquire a lock.