This is entirely dependant on the OS, but if you have one CPU socket you will have trouble seeing any error using nanoTime. If you use Wiindows 7+ or a recent version of Linux, nanoTime corrects for the differences between sockets. BTW If you have a multi-socket XP box you can see nanoTime jump backwards and forwards by a few milli-seconds. (In short don't use XP on multi-socket machines and expect a good outcome)
Also note that some OSes have only micro-second resolution. This means you can have many operations performed between threads and they all appear to have the same time stamp. The solution to this is to use an OS with higher resolution timers. This doesn't involve changing your code or even your JVM.
Is it perhaps possible for threads created by the same process to be executed in different JVMs?
I don't know of any way for this to be possible, nor can I think of a reason this would matter. The same system call is made regardless of which thread, JVM or process you are using.
This would explain the erroneous behaviour of nanoTime but still it doesn't make too much sense. Any ideas?
Most likely you only have micro-second resolution for the call nanoTime() calls on your OS.
read x // reads false while time before reading is 0001
If you have better than micro-second timing, every call to nanoTime() is likely to be different. An update to a volatile variable via the cache takes a minimum of 75 clock cycles or ~20 nano-seconds. Nothing is instant, and I have seen delays of closer to 100 nano-second for delays between thread for trivial updates between threads.