Hi Maria,
Here's what I think is happening:
After line 6 executes we have two threads in a runnable state: the main one (
thread main) and the one executing the run method of class A (thread 0).
By means of lines 1 and 7 they both fight for the lock on
String array sa which at this point (after line 6) is
a[0]->"Not Done", a[1]->"X", a[2]->"Y", a[3]->"Z"
.
Scenario 1
Thread 0 gets the lock first, line 1 executes before line 7.
Compares sa[0] with "Done" which results in false.
Enters the while loop and executes the wait method of the sa object.
The wait method makes the calling thread unlock all it's locks (including the lock on sa) and puts the thread to "sleep" but unlike the sleep method doesn't keep the locks.
While thread 0 sleeps thread main who in the main time was blocked waiting at line 7 suddenly finds the sa String array unlocked, locks it and executes lines 8,9,10,11,12 and exits the block.
Now sa is:
a[0]->"Done", a[1]->"A", a[2]->"B", a[3]->"C"
Line 12 sends a notification to one of the threads (in this case only one, thread 0) waiting for the sa object and wakes up a thread (here thread 0).
Thread 0 wakes up, executes line 2, finds the expression false and exits the loop and executes line 4 printing ABC.
Scenario 2
Thread main gets the lock first, line 7 executes before line 1.
Thread main locks sa, executes lines 8,9,10,11,12 and exits the block.
Thread 0 finds the while expression on line 2 false and doesn't even bother to enter the while loop but goes directly to line 4 and prints ABC.
Hope this was helpful and I hope I didn't oversee anything.