Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use the volatile keyword in Java correctly?

Tags:

java

volatile

Say I have two threads and an object. One thread assigns the object:

public void assign(MyObject o) {
    myObject = o;
}

Another thread uses the object:

public void use() {
    myObject.use();
}

Does the variable myObject have to be declared as volatile? I am trying to understand when to use volatile and when not, and this is puzzling me. Is it possible that the second thread keeps a reference to an old object in its local memory cache? If not, why not?

Thanks a lot.

like image 830
Tiyoal Avatar asked Jun 03 '10 16:06

Tiyoal


3 Answers

I am trying to understand when to use volatile and when not

You should mostly avoid using it. Use an AtomicReference instead (or another atomic class where appropriate). The memory effects are the same and the intent is much clearer.

I highly suggest reading the excellent Java Concurrency in Practice for a better understanding.

like image 165
Kevin Avatar answered Nov 18 '22 15:11

Kevin


Leaving the complicated technical details behind, you can see volatile less or more as a synchronized modifier for variables. When you'd like to synchronize access to methods or blocks, then you'd usually like to use the synchronized modifier as follows:

public synchronized void doSomething() {}

If you'd like to "synchronize" access to variables, then you'd like to use the volatile modifier:

private volatile SomeObject variable;

Behind the scenes they do different things, but the effect is the same: the changes are immediately visible for the next accessing thread.

In your specific case, I don't think that the volatile modifier has any value. The volatile does not guarantee in any way that the thread assigning the object will run before the thread using the object. It can be as good the other way round. You probably just want to do a nullcheck in use() method first.

Update: also see this article:

Access to the variable acts as though it is enclosed in a synchronized block, synchronized on itself. We say "acts as though" in the second point, because to the programmer at least (and probably in most JVM implementations) there is no actual lock object involved.

like image 22
BalusC Avatar answered Nov 18 '22 15:11

BalusC


Declaring a volatile Java variable means:

  • The value of this variable will never be cached thread-locally
  • Access to the variable acts as though it is enclosed in a synchronized block

The typical and most common use of volatile is :

public class StoppableThread extends Thread {
  private volatile boolean stop = false;

  public void run() {
    while (!stop) {
      // do work 
    }
  }

  public void stopWork() {
    stop = true;
  }
}
like image 4
aleroot Avatar answered Nov 18 '22 16:11

aleroot