Chris,
Thanks for sharing. I also want to share some finding, though pretty predictable.
So, yes, it's this piece of code from Effective Java. I don't copy it here, everyone can find it in Item 66. What i found out, if you run on Windows with JVM option -server, it works as promised! Second thread never notices the change of "stopped" made in main thread. Interestingly enough, this piece of code can be useful to find out when java standard API uses synchronized. E.g. unexpected (for me): if you put inside run() loop a line like
Integer iObj = new Integer(), the "stopped" becomes visible in thread! Like if you use System.out.print(). But
Object obj = new Object() does not produce that effect.
Another example where non-volatile suppose to break, from the Paul Hyde "Java Thread Programming" book (p.122) seems does not work for 1.5 and later and can't be completely fixed, because in 1.5 one volatile class member can change semantics of others non-volatile members. However, if remove volatile declaration from all class members completely, it's getting really interesting, the example shows (again and in different way) that non-volatile members are not visible.
I know it all of a little practical interest, and I stop now that thread. But interesting ... like in J. Bloch puzzles. And no, I am not teaching, except only myself