This content has been marked as final. Show 4 replies
JavaFunda wrote:Roughly speaking, the first time a thread reads a shared (or potentially shared) variable after entering a sync block or method, it must read it from the main copy. Additionally, upon exiting the sync block/method, the thread must write any shared variables that has changed locally back out to the main copy. The actual rules are more complex than that, but that's more or less what it amounts to. Within the body of the sync block/method, however, threads are free to use local copies for shared variables as much as they want. It's only the entry/exit boundaries that matter.
Does synchronized methods internally write to main memory (i mean they dont keep the local copy )? so no need of declaring the shared variable as volatile, if operation on shared variable is occuring under synchronized methods/blocks. Is it correct?
Therefore, if all access to a given variable is synchronized, there's no need to declare that variable volatile.
Conceptually, you can think of all reads/writes in a synchornized block as being accesses to main memory.
However, depending on your CPU architecture, the caches can have a protocol where they talk to each other and instead of getting data from main memory or forcing data to be written to main memory the caches pass data between themselves. e.g. x86/x64 does this even between caches on different CPUs.
You shouldn't need to worry that using a synchronized block will slow down access to data as much as the difference between L1 cache and main memory (typically 5x or more). The difference can be less than 50% slower.
Synchronized and the Java Spec in general only determines the behaviour required, it doesn't define the implementation.
EJP wrote:Correctness is almost always more important than performance. Performance counters the only example I can think of when performance is more important than correctness.
You shouldn't need to worry that using a synchronized block will slow down access to dataI don't think he is, and worrying about the difference between a correct result and an incorrect result is futile. You can get the wrong answer in zero time if you want it.
However I have seen developers go to great lengths to get a correct solution which avoids using synchronized when it wasn't obvious to me that a) its wasn't a maintenance nightmare b) was needed c) was actually faster.
In Java 5.0 Lock was added and it was much faster than synchronized, and even though it made the code less clear and more prone to bugs, there was a shift to using it. However Java 6 came along and the performance difference narrowed and you would have to think twice (or more) about changing it for performance reasons.