Compile and run the program for a short moment, and you will see the following History Graph window. Philosopher 1 first waits to enter the monitor (i.e., the MB tag). Eventually, it has the chance (i.e., the MA tag). Now, it is in the monitor, and, of course, can take the chopsticks. After it exits the monitor (i.e., the ME tag), philosopher 1 is eating, and the monitor is given to one of the waiting threads. From the history bar, philosopher 2 gets the monitor, and is blocked (i.e., the CW tag) because one of his chopsticks (i.e., chopstick 2) is taken and being used by philosopher 1. Blocking philosopher 2 causes philosopher 3 to enter (i.e., the MA tag). Because chopsticks 3 and 4 are free, philosopher 3 takes them and exits the monitor. After this, philosopher 3 is eating. Note that before philosopher 2 blocks, philosopher 1 finishes eating and comes back to return chopsticks 1 and 2 (i.e., the MB tag). When philosopher 3 exits, philosopher 4 enters, and is blocked because his chopstick 4 is being used by philosopher 3. The blocking of philosopher 4 gives a chance for philosopher 0 to enter. This is what we learn from the History Graph window.
From the above snapshot, we know that philosopher 0 is in the monitor trying to get his chopsticks 0 and 1. Philosophers 2 and 4 are blocked by their own condition variables self[2] and self[4], respectively. Philosophers 1 and 3 are waiting to enter in order to return their chopsticks. Hence, the states of these philosophers are philosopher 0 - hungry, philosopher 1 - eating, philosopher 2 - hungry, philosopher 3 - eating, and philosopher 4 - hungry. The main window and the Monitor window summarize this finding:
Let us continue with the above execution, which is shown in the second half of the following History Graph window. Now, philosopher 0 is in the monitor and blocks because his chopstick 1 is being held by philosopher 1. Then, philosopher 1 can enter and return his chopsticks 1 and 2. This changes the state of philosopher 1 to thinking. Method Test() is used to release philosopher 0 and philosopher 2. Since the neighbors of philosopher 0 (i.e., philosopher 4 and philosopher 1) are not eating, philosopher 0 is signaled and released. This is shown by the line segment between the CY tag of philosopher 1 and the CA tag of philosopher 0. Note that philosopher 1 yields the monitor because this is a Hoare type monitor. Now, philosopher 0 is running, takes his chopsticks, exits the monitor (i.e., the ME tag), and starts to eat. After philosopher 0 exits, philosopher 1 resumes his execution and becomes active again (i.e., the MR tag), because there is no other inactive thread. However, the second call to method Test() is not able to release philosopher 2 because his chopstick 3 is currently being used by philosopher 3. As a result, philosopher 1 has only one CY tag, and then exits. This makes philosopher 3 to enter and return chopsticks 3 and 4. This causes philosopher 2 to be released. Will philosopher 4 be released?