views:

3362

answers:

11

In work today, I came across the volatile keyword in Java. Not being very familiar with it, I found this explaination: http://www.ibm.com/developerworks/java/library/j-jtp06197.html

Given the detail in which that article explains the keyword in question, do you ever use it or could you ever see a case in which you could use this keyword in the correct manner?

+2  A: 

Here's a good article on the topic.

http://pitfalls.wordpress.com/2008/05/25/javavolatile/

Ben Hoffstein
+14  A: 

“… the volatile modifier guarantees that any thread that reads a field will see the most recently written value.” - Josh Bloch

If you are thinking about using volatile, read up on the package java.util.concurrent which deals with atomic behaviour.

The Wikipedia post on a Singleton Pattern shows volatile in use.

_ande_turner_
A: 

Absolutely, yes. (And not just in Java, but also in C and C#.) There are times when you need to get or set a value that is guaranteed to be an atomic operation on your given platform, an int or boolean, for example, but do not require the overhead of thread locking. The volatile keyword allows you to ensure that when you read the value that you get the current value and not a cached value that was just made obsolete by a write on another thread.

dgvid
+32  A: 
Greg Mattes
I concur - I've used volatile for the exact same reason - tracking when to end a loop in a multi-threaded application.
Darren Greaves
+4  A: 

One common example for using volatile is to use a volatile boolean variable as a flag to terminate a thread. If you've started a thread, and you want to be able to safely interrupt it from a different thread, you can have the thread periodically check a flag. To stop it, set the flag to true. By making the flag volatile, you can ensure that the thread that is checking it will see it has been set the next time it checks it without having to even use a synchronized block.

Dave L.
+2  A: 

Yes, volatile must be used whenever you want a mutable variable to be accessed by multiple threads. It is not very common usecase because typically you need to perform more than a single atomic operation (e.g. check the variable state before modifying it), in which case you would use a synchronized block instead.

ykaganovich
A: 

You'll need to use 'volatile' keyword, or 'synchronized' and any other concurrency control tools and techniques you might have at your disposal if you are developing a multithreaded application. Example of such application is desktop apps.

If you are developing an application that would be deployed to application server (Tomcat, JBoss AS, Glassfish, etc) you don't have to handle concurrency control yourself as it already addressed by the application server. In fact, if I remembered correctly the J2EE standard prohibit any concurrency control in servlets and EJBs, since it is part of the 'infrastructure' layer which you supposed to be freed from handling it. You only do concurrency control in such app if you're implementing singleton objects. This even already addressed if you knit your components using frameworkd like Spring.

So, in most cases of Java development where the application is a web application and using IoC framework like Spring or EJB, you wouldn't need to use 'volatile'.

Rudi Adianto
+1  A: 

Yes, I use it quite a lot - it can be very useful for multi-threaded code. The article you pointed to is a good one. Though there are two important things to bear in mind:

  1. You should only use volatile if you completely understand what it does and how it differs to synchronized. In many situations volatile appears, on the surface, to be a simpler more performant alternative to synchronized, when often a better understanding of volatile would make clear that synchronized is the only option that would work.
  2. volatile doesn't actually work in a lot of older JVMs, although synchronized does. I remember seeing a document that referenced the various levels of support in different JVMs but unfortunately I can't find it now. Definitely look into it if you're using Java pre 1.5 or if you don't have control over the JVMs that your program will be running on.
MB
+5  A: 

volatile is very useful to stop threads.

Not that you should be writing your own threads, Java 1.6 has a lot of nice thread pools. But if you are sure you need a thread, you'll need to know how to stop it.

The pattern I use for threads is:

public class Foo extends Thread {
  private volatile boolean close = false;
  public void run() {
    while(!close) {
      // do work
    }
  }
  public void close() {
    close = true;
    // interrupt here if needed
  }
}

Notice how there's no need for synchronization

Pyrolistical
A: 

volatile ensure you ,The value you are accessing is the current value in multi Threaded enviroment with acquiring a lock on object.

deepak gupta
A: 

One common example for using volatile is to use a volatile boolean variable as a flag to terminate a thread. If you've started a thread, and you want to be able to safely interrupt it from a different thread, you can have the thread periodically check a flag. To stop it, set the flag to true. By making the flag volatile, you can ensure that the thread that is checking it will see it has been set the next time it checks it without having to even use a synchronized block.

"interrupt from a different thread", then how would you answer, why you need 'volatile' field to hold the cancellation state when the same thread starts the thread and invokes cancel?

package net.jcip.examples;

import static java.util.concurrent.TimeUnit.SECONDS; import java.math.BigInteger; import java.util.; import java.util.concurrent.;

import net.jcip.annotations.*;

/** * PrimeGenerator * * Using a volatile field to hold cancellation state * * @author Brian Goetz and Tim Peierls */ @ThreadSafe public class PrimeGenerator implements Runnable { private static ExecutorService exec = Executors.newCachedThreadPool();

@GuardedBy("this") private final List<BigInteger> primes
        = new ArrayList<BigInteger>();
private volatile boolean cancelled;

public void run() {
    BigInteger p = BigInteger.ONE;
    while (!cancelled) {
        p = p.nextProbablePrime();
        synchronized (this) {
            primes.add(p);
        }
    }
}

public void cancel() {
    cancelled = true;
}

public synchronized List<BigInteger> get() {
    return new ArrayList<BigInteger>(primes);
}

static List<BigInteger> aSecondOfPrimes() throws InterruptedException {
    PrimeGenerator generator = new PrimeGenerator();
    exec.execute(generator);
    try {
        SECONDS.sleep(1);
    } finally {
        generator.cancel();
    }
    return generator.get();
}

}