Detailed Example of Interpretation
|
![]() |
In this program there are 4 threads and 1 object.
On the left hand side picture, the main thread has created the 3 other threads (2 consumers and 1 producer) and the object (CubbyHole). It has also started the thread Consumer #2 which is currently "executing" (thicker blue border on the node). |
![]() |
Later during execution, the main thread is "dead" (black node).
The 3 threads have been started. Consumer #2 and Producer #4 are "runnable" and Consumer #5 is "executing". CubbyHole is "locked" by Consumer #2 (presence of a L-arrow and dark blue color for CubbyHole). |
![]() |
Later again, Consumer #5 tried to access CubbyHole (call to the synchronized get method)
and is now "blocked" (shown in red and with a B-arrow).
Consumer #5 is waiting for the lock on CubbyHole (which is still owned by Consumer #2). |
![]() |
Further execution of the program turns Producer #4 into the "blocked" status, waiting for the lock
on CubbyHole (still owned by Consumer #2).
So, there are now 2 "blocked" threads (visible in red). |
![]() |
On the left hand side picture, a lock is released (object CubbyHole and its lock are now in light
blue) by Consumer #2.
Consumer #2 becomes "dormant" (purple color and linked to the CubbyHole lock by a D-arrow) because it has locked the CubbyHole before the Producer #4 has put a value in it (and therefore has no value to read). So Cunsumer #2 has called the wait method in order to enable Producer #4 to get the lock on CubbyHole. There are still 2 "blocked" threads waiting for a lock on CubbyHole. |
![]() |
Finally, one of these 2 "blocked" threads will resume execution
arbitrarily and will hold this lock (Producer #4).
Eventually both Producer #4 and Consumer #5 will successively release the lock and Consumer #2 will resume. |