The key point is that both threads synchronize on the same object, the 3 element
String[] array. The pupose of this is to be sure that references to the string literals "A", "B", and "C" are stored in the array by B.main() before A.run() prints the array.
B.main() takes the lock on the array, using sa as a reference. B.main() then creates an A object, passing the array reference to the A(String[]) constructor. That constructor saves the passed reference to the String[] array in saa.
B.main() then starts the second
thread, but that thread immediately blocks on the String[] object lock held by the main thread.
When B.main() finishes initializing the array, it releases the lock and exits, ending the main thread.
A.run() now unblocks and takes the lock on the array. It prints the 3 array elements as ABC and exits, terminating the second thread.