I have been researching the Java Memory Model all day today, in order to understand in detail the problems with the JMM pre-Java 5 and the changes made by JSR-133 implemented in Java 5.
What I cannot seem to find a definitive answer on is the scope of cache invalidation and flushing required on a particular synchronize.
Must all CPU registers and caches be invalidated when entering any synchronized portion of code and all flushed to main RAM when leaving, or is the JVM allowed to only invalidate those variables actually read, and flush only those actually written during the synchronized block of code?
If the former, why is the JMM so pedantic about insisting the that memory barrier only occurs between two threads which synchronize on exactly the same object?
If the latter, is there any good document that explains the details of how this is accomplished? (I would suppose the underlying implementation would have to set a "bypass caches" flag at the CPU level at the start of a synchronized block and clear it at the end, but I could be way off base.)