Personally I believe the answer should be option 3. The call to wait() may return at any moment, because of spurious wakeups. So the program may print some arbitrary value between 0 and 999999, or it may not terminate at all.
There is no correlation between the finishing of the run() method and the release of locks or notification. However, there may be a correlation between the finishing of a run() method and spurious wakeups.
I tested the program myself, and it indeed prints 999999, but I don't think this can be guaranteed. If I remove the thread.start() statement, the program runs indefinitely, so I believe the termination of a thread may cause other wait() statements to return spuriously. Again, this is an artifact of the implementation, and the results may differ on different operating systems or different virtual machines.
The call to wait() may return at any moment, because of spurious wakeups.
I'm not sure what is meant by this. In given code, nobody is explicitly calling notify/notifyAll method on thread, so it is very very unlikely (rather I would say impossible) to get out of wait method before thread execution is finished. Once run method is executed, 'wait' will be over.
If I remove the thread.start() statement, the program runs indefinitely
This happened because, thread was not running, nobody's gonna ever call notify/notifyAll on that thread, and hence 'wait' will never end.
Hence, in my opinion, output should (and would) be 999999.