Search code examples
javasynchronizationsynchronizedvolatile

Do variables accessed within synchronised block must be declared volatile?


in an example like this:

...
    public void foo() {
        ...
        synchronized (lock) {
            varA += some_value;
        }
        ...
    }
...

The question is, does varA must be declared volatile in order to prevent per-thread caching or it is enough to access it only within synchronized blocks?

Thanks!


Solution

  • No, you don't need to.
    synchronized blocks imply a memory barrier.

    From JSR-133:

    But there is more to synchronization than mutual exclusion. Synchronization ensures that memory writes by a thread before or during a synchronized block are made visible in a predictable manner to other threads which synchronize on the same monitor. After we exit a synchronized block, we release the monitor, which has the effect of flushing the cache to main memory, so that writes made by this thread can be visible to other threads. Before we can enter a synchronized block, we acquire the monitor, which has the effect of invalidating the local processor cache so that variables will be reloaded from main memory. We will then be able to see all of the writes made visible by the previous release.