A monitor object is an object whose intrinsic synchronization coordinates exclusive access among threads. A synchronized block uses the monitor to admit one thread while others wait at the block’s entrance. section 7.1
A shared ArrayList can serve as the monitor for producer and consumer threads. Both synchronize on the same list, so only one thread changes it at a time; code outside the synchronized block can still run concurrently. section 7.1
Distinguish the monitor states that appear during investigation:
- Locked means a thread is blocked at the entrance because another thread actively occupies the synchronized block. section 7.3
- Waiting means the monitor has explicitly made a thread wait; execution resumes only after notification by the same monitor. section 7.3
- Calling wait when the list is empty and notifyAll after producing or consuming values coordinates the bounded producer-consumer flow. section 7.3
- Nested synchronized blocks become dangerous when threads acquire the same monitors in reverse order, allowing each to wait for the other indefinitely. section 8.1
Tracing a contended list monitor
The producer adds random integers while the consumer removes them. Profiling identifies the ArrayList instance and its object reference, then shows which thread blocked the other and how often. In the demonstrated run, each thread blocked the other 3,698 times through the same monitor. section 7.2
Figure 7.8 The profiling results give us a good understanding of what creates locks and what is affected by them. We see that there’s only one monitor the producer thread works with. Also, the consumer thread blocked the producer thread 3,698 times using the monitor. Using the same monitor instance, the producer blocked the consumer for the same number of times: 3,698.
Inspect the monitor reference, blocked threads, owning threads, and repeated lock events to connect runtime behavior with synchronized code. section 7.2
