Not sure what you are talking about, since the example you showed is not an example in the book... Unless you are talking about the example chapter, and are trying test something in it?
Assuming that you are trying to test the fact that volatile variables may be cached... the example may run forever, it may run for many iterations after you set the done flag, or it may exit immediately depending on the JVM you are using.
But... in my opinion, you probably set the done flag before you given the new thread a chance to start. Put in a delay before setting the flag, and see what happens.
There are two threads involved here. The thread started with the main method have the preference here because it is alreasdy executing. When the line v.start is executed a new thread will wait for the current thread to finish. Because of this the current thread sets the done flag to true. Then the current thread will terminate. Then the waiting thread v.start takes precedence. But there is no guarantee on which thread will take precedence. Only thing sure is that there is more probability of having the CPU time slot available to main thread.
Similar to giving a wait which will difinitely make the main thread wait, try the code below.
This will show the relation between input output operations and CPU time slots
The output will look like follows.
[LINK] Run atThu Oct 28 11:31:27 CDT 2004 Foo Run atThu Oct 28 11:31:27 CDT 2004 Foo .. .. .. Foo Run atThu Oct 28 11:31:27 CDT 2004 Foo set atThu Oct 28 11:31:27 CDT 2004 Run atThu Oct 28 11:31:27 CDT 2004 Foo
See the thread looses precedence in between print("set at.) and done = true; This is because time slots ends after printing set atThu Oct 28 11:31:27 CDT 2004 So the main thread loses precedence again.
The output varies with OS and CPU utilization since the time slices and precedence varies.