Search code examples
javamultithreadingsynchronizationvolatile

synchronize without volatile


I understand what synchronize and volatile does and where they are used. I just learned volatile and I was confused about when could we use synchronize without volatile. if I synchronize an object I need to block other threads from using the same object , but in most cases I would do that to edit the object, if so I need to have volatile on that attributes I'm editing .

The following code is about race condition and I wonder why I've never seen someone using volatile on count variable :

  public synchronized void add(int value){
      this.count += value;
  }

shouldn't be count volatile here ?

I'm just trying to figure a case where synchronize can be used without volatile , a piece of code will help.


Solution

  • It is evident that volatile is not strong enough to implement a counter because it does not guarantee atomicity. However, if reads greatly outnumber modifications, you can combine intrinsic locking and volatile variables to reduce the cost on the common code path. Check this out,

    public class Counter {
        @GuardedBy("this") private volatile int value;
    
        public int getValue() { return value; }
    
        public synchronized int increment() {
            return value++;
        }
    }
    

    The code uses synchronized to ensure that the increment operation is atomic and uses volatile to guarantee the visibility of the current result. If updates are infrequent, this approach may perform better as the overhead on the read path is only a volatile read, which is generally cheaper than a lock acquisition.