The output could never be "XYZ".
Let's look through the flow of the application a little bit. We start with this line:
Next, we create a new thread and pass it that
String array. Once created, we kick off that thread.
Now this is where it can be a little tricky. What gets executed next? Is it going to next execute the synchonized block in main or the synchronized block in the new thread? Simply put, we just don't know.
Let's assume, that the new thread executes first. It acquires the lock on the String array object with this line:
Then in the next line, it checks the first index of the String array and compares it to the String literal "Done":
Well, at this point, sa[0] contains the String "Not Done". Therefore, this check succeeds (the inverse of sa[0].equals("Done"), which is false, is true). With that check succeeding, we jump into the while block and execute this line:
This causes this thread to move out of the running state and go into a waiting state. At this point, the new thread is done processing.
Now, with only one other thread to execute (that being the main thread), we know what's going to execute next. We'll next execute this line in the main method:
Because the new thread had invoked the wait method, it gave up the lock it had on the String array object. That allows the main thread to acquire it and move into it's synchronized block. The following lines are then executed:
This changes the contents of the String array object and, when done, performs a notify. There is only 1 thread waiting at this point so we know which thread is going to be awakened by this call. That is, of course, our new thread. When that thread wakes up, we pick up where it left off, after that wait() statement. As this was inside a loop, we again check the loop condition:
Now that the main thread modified the contents of our String array, we know that sa[0]
does contain the String "Done". Therefore, this loop condition fails and we exit the loop. That takes us to this line:
Once again, the String array has already been modified so we now spit out "ABC".
Hopefully, you see that there is no way the output line can be executed before the String array has been modified by the main thread. The new thread will constantly wait for the main thread to complete before it can finish it's run method.
I hope that helps,
Corey