The Java Memory Model is something that most developers don’t understand, even though this knowledge is mandatory to create concurrent code that works without problems on any Java platform. A Memory Model describes under what conditions a write done by one thread, will be visible to another thread that does a read. Most developers think that the write of normal variables without any synchronization actions, is going to be visible to any reading thread (this behavior is called sequential consistency). They don’t realize that Java doesn’t provide this behavior out of the box, because it would prevent a lot of optimizations from being used (out of order execution of instructions, use of caches/registers etc).
The ‘nice’ thing is that code with JMM problems is not going to behave badly on a lot of modern hardware in a lot of cases. This is because most hardware provides a very strong cache coherence (far stronger than the JMM requires), so a value written in one cache is probably going to be visible in the other caches, even though synchronization actions are missing. The fact that the problems are not ‘that bad’ or ‘have not occurred’ is an argument I hear quite often.
The question remains of course if relying on the hardware to ‘fix’ a faulty application is a good approach. If the application is going to run on hardware that provides a much weaker cache coherence, very hard to track down problems could happen. This means that the Java application is not platform independent anymore. Another problem is that not just the cache could cause Memory Model problems, but the compiler can cause it as well. Currently it already is possible that a compiler optimization could break an application, no matter how strong the cache coherence of the underlying hardware is. And no guarantees can be made that a future JVM is not going to optimize much more aggressive, so even using a different JVM could cause problems.
Maybe it would have been better if the hardware didn’t provide such a strong cache coherence, so that writing correct concurrent code would have a much higher priority.