Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Volatile with synchronized together

Is there any reason to use volatile and synchronized together in this code?

public class Helper {
  private volatile int n;
  private final Object lock = new Object();
  public Helper(int n) {
    this.n = n;
  }

  public void setN(int value) {
    synchronized (lock) {
      n = value;
    }
  }
}

Class Helper must be thread safe. I've got this example from the "Java Concurrency Guidelines" book, but it is still not clear: what is the reason for using volatile and synchronized together in this example?

like image 883
Vladimir Korobkov Avatar asked Apr 12 '12 11:04

Vladimir Korobkov


People also ask

Is volatile needed with synchronized?

If it is accessed only from synchronized blocks is not needed the volatile keyword. Synchronized guarantees that changes to variables accessed inside the synchronized block are visible to all threads entering a synchronized block.

Is volatile variable synchronized?

Effectively, a variable declared volatile must have it's data synchronized across all threads, so that whenever you access or update the variable in any thread, all other threads immediately see the same value. Generally volatile variables have a higher access and update overhead than "plain" variables.

How do you use synchronized and volatile in your Java application?

We may use the synchronized keyword for maintaining thread safety. However, the volatile keyword is essentially lock-free and hence the most lightweight means of providing thread safety. Declaring a Volatile Variable Simply Means: The value of this variable will never be cached in the threads' caches locally.

Can we use synchronized with variable in Java?

You can have both static synchronized method and nonstatic synchronized method and synchronized blocks in Java but we can not have synchronized variable in java. Using synchronized keyword with a variable is illegal and will result in compilation error.


2 Answers

The purpose of this example is to point out that syncronized without volatile isn't enough in this case given the fact that object can be published unsafely (i.e. without volatile in Foo):

If the helper field in the Foo class is not declared volatile, the n field should be declared volatile so that a happens-before relationship is established between the initialization of n and the write of Helper to the helper field. This is in compliance with guideline “VNA06-J. Do not assume that declaring an object reference volatile guarantees visibility of its members” on page 35. This is required only when the caller (class Foo) cannot be trusted to declare helper volatile.

That's correct, but they chose a bad example to demonstrate it, because volatile without syncrhonization is enough in this case.

like image 90
axtavt Avatar answered Nov 15 '22 16:11

axtavt


It's not necessary to put the synchronised block around the change in value; since Java 5 this is done "automatically" for volatile variables. I think that previous to Java 5, it was not necessarily the case.

like image 28
John Farrelly Avatar answered Nov 15 '22 18:11

John Farrelly