wood burning stoves*
The moose likes Threads and Synchronization and the fly likes Volatile and Snoopy Caches Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Volatile and Snoopy Caches" Watch "Volatile and Snoopy Caches" New topic
Author

Volatile and Snoopy Caches

Thomas Punihaole
Greenhorn

Joined: Jan 12, 2012
Posts: 4
I apologize if this has been asked before but the volatile keyword is a confusing one for many people (including myself).

Many programmers argue that the volatile keyword simply means that the variable is not cached. If the hardware supports snoopy caches than this would seem unnecessarily restrictive.

A second definition is that a variable with the volatile modifier orders the accesses to it. How does this differ from the synchronized keyword? Is synchronized not thread fair?

Obviously the volatile keyword is needed for implementing the double-checked lock pattern, but what other uses does it serve? It seems like one would be better served using some synchronization primitives instead of relying on the volatile's ordering of accesses? Stated differently, has anyone here used volatile successfully and satisfactorily in any of their projects?
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Thomas Punihaole wrote:I apologize if this has been asked before but the volatile keyword is a confusing one for many people (including myself).

Many programmers argue that the volatile keyword simply means that the variable is not cached. If the hardware supports snoopy caches than this would seem unnecessarily restrictive.

A second definition is that a variable with the volatile modifier orders the accesses to it. How does this differ from the synchronized keyword? Is synchronized not thread fair?


If you slog through the relevant sections of the JLS, you'll find that volatile guarantees that every read and write of a volatile variable goes against the JVM's main copy, not against any thread's local copy. (And note that how the JVM implements "main" and "thread-local" copies is left up to the implementation, and not tied to any specific hardware features.) This means that as soon as any thread writes to a volatile, that volatile's value is immediately visible to any thread that might read it. You can accomplish the same thing with synchronization, but it's more verbose, and requires every read and write access to that variable to be explicitly synced on the same lock.

Additionally, http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.3.1.4 says, "...guarantees that accesses to the shared values for i and j occur exactly as many times, and in exactly the same order, as they appear to occur during execution of the program text by each thread. " (Details, however, are in Chapter 17)

Obviously the volatile keyword is needed for implementing the double-checked lock pattern,


Which I don't believe there's ever any good reason to use.

but what other uses does it serve?


If you simply want to ensure that a given thread's write of a variable is immediately visible to all other threads that might be doing a read, but don't need atomicity of multi-step tasks, then declaring the variable volatile is simpler than using synchornization. For instance, a private boolean done; variable that is set by one thread to indicate that another thread should stop its run method's main loop.

Stated differently, has anyone here used volatile successfully and satisfactorily in any of their projects?


Yes.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18760
    
  40

Jeff Verdegan wrote:
but what other uses does it serve?


If you simply want to ensure that a given thread's write of a variable is immediately visible to all other threads that might be doing a read, but don't need atomicity of multi-step tasks, then declaring the variable volatile is simpler than using synchornization. For instance, a private boolean done; variable that is set by one thread to indicate that another thread should stop its run method's main loop.

Stated differently, has anyone here used volatile successfully and satisfactorily in any of their projects?


Yes.


Agree with everything, but I like to add one little point. Volatile variables is not just a simple JVM trick that removes the need to have synchronization of simple setters and getters. The atomic libraries (java.util.concurrent.atomic) depends on it (along with other stuff), and using the atomic libraries, you can deal with multi-step tasks that need to be atomic, and without the need for syncrhonization.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Henry Wong wrote:
Agree with everything, but I like to add one little point. Volatile variables is not just a simple JVM trick that removes the need to have synchronization of simple setters and getters. The atomic libraries (java.util.concurrent.atomic) depends on it (along with other stuff), and using the atomic libraries, you can deal with multi-step tasks that need to be atomic, and without the need for syncrhonization.


I wouldn't call it a "simple JVM trick", but there's nothing that you can do with volatile that you can't do with synchronization. I would consider volatile simply a lighter weight language primitive that gives coherence but not atomicity (other than making reads and writes of doubles and longs atomic when they otherwise might not be).

As for the atomic libs, they've only been around since 1.5, whereas volatile has been around since the beginning, or very nearly so. Part of the role of the atomics, IMHO, is as higher level abstraction versions of volatile, at least for simple reads and writes. The multi-step getAndSet() type operations cannot be done just with volatile, of course, and their implementations must use synchronization, or perhaps some mechanism internal to the VM (I've never actually looked into their implementation). Certainly just using volatile doesn't provide the ability to do multi-step operations, like getAndSet(), atomically.

Martin Vajsar
Sheriff

Joined: Aug 22, 2010
Posts: 3610
    
  60

Jeff Verdegan wrote:As for the atomic libs, they've only been around since 1.5, whereas volatile has been around since the beginning, or very nearly so. Part of the role of the atomics, IMHO, is as higher level abstraction versions of volatile, at least for simple reads and writes. The multi-step getAndSet() type operations cannot be done just with volatile, of course, and their implementations must use synchronization, or perhaps some mechanism internal to the VM (I've never actually looked into their implementation). Certainly just using volatile doesn't provide the ability to do multi-step operations, like getAndSet(), atomically.

If I remember it correctly, the meaning of volatile keyword was somewhat beefed up in Java 5. It was not very useful in older Java versions.

I've looked into AtomicInteger implementation and found out that it uses the Unsafe class. That allows for platform-specific implementation.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Martin Vajsar wrote:
If I remember it correctly, the meaning of volatile keyword was somewhat beefed up in Java 5. It was not very useful in older Java versions.


My understanding is that it has always meant the same thing--or was always intended to--but that the spec was poorly worded prior to 1.3 or 1.4, which led to implementations that were strictly legal but that didn't meet the intended use, and that's why it was not useful or reliable.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18760
    
  40

Jeff Verdegan wrote:As for the atomic libs, they've only been around since 1.5, whereas volatile has been around since the beginning, or very nearly so. Part of the role of the atomics, IMHO, is as higher level abstraction versions of volatile, at least for simple reads and writes. The multi-step getAndSet() type operations cannot be done just with volatile, of course, and their implementations must use synchronization, or perhaps some mechanism internal to the VM (I've never actually looked into their implementation). Certainly just using volatile doesn't provide the ability to do multi-step operations, like getAndSet(), atomically.


The key method in the atomic libraries is the compareAndSet() method. This is implemented via JNI, which in turn, goes directly to the CAS operator. This means that compare and set is done atomically and without any synchronization.

The other methods, such as get and set, is done with the compare and set method, along with retries upon failure.... ie. done optimistically. And again, without any synchronization. The cool part of the atomic libararies is that you can get really elaborate with it, you can load tons of variables, do very complex operations, and change tons of variables -- all atomically without synchronization. It just have to be done optimistically -- meaning it can fail causing a retry, and wasted CPU cycles.

Henry
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Henry Wong wrote:
Jeff Verdegan wrote:As for the atomic libs, they've only been around since 1.5, whereas volatile has been around since the beginning, or very nearly so. Part of the role of the atomics, IMHO, is as higher level abstraction versions of volatile, at least for simple reads and writes. The multi-step getAndSet() type operations cannot be done just with volatile, of course, and their implementations must use synchronization, or perhaps some mechanism internal to the VM (I've never actually looked into their implementation). Certainly just using volatile doesn't provide the ability to do multi-step operations, like getAndSet(), atomically.


The key method in the atomic libraries is the compareAndSet() method. This is implemented via JNI, which in turn, goes directly to the CAS operator. This means that compare and set is done atomically and without any synchronization.


Right, that's the basic operation that has to present down to the hardware level if you want to do any multi-step operation atomically in a multithreaded environment. I assumed the concurrent libs used that, since they supposedly can offer better performance than we could get ourselves using syncing.


The other methods, such as get and set, is done with the compare and set method, along with retries upon failure.... ie. done optimistically. And again, without any synchronization. The cool part of the atomic libararies is that you can get really elaborate with it, you can load tons of variables, do very complex operations, and change tons of variables -- all atomically without synchronization. It just have to be done optimistically -- meaning it can fail causing a retry, and wasted CPU cycles.

Henry


Yeah, it's very cool stuff. I've only scratched the surface of it, but I like having these higher level abstractions instead of having to roll everything by hand using synchronization.
Thomas Punihaole
Greenhorn

Joined: Jan 12, 2012
Posts: 4
Thanks for the replies guys. I suspected that using volatile isn't necessary when you can use synchronization. I guess this is still true but volatile has some subtle applications which you mentioned.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Thomas Punihaole wrote:Thanks for the replies guys. I suspected that using volatile isn't necessary when you can use synchronization.


Well, you can always use synchronization, so it's never really necessary. If I had to summarize, I'd say:

1) Volatile is lighter weight code-wise and CPU-wise than syncing.

2) Volatile provides the same variable coherency as syncing, but no multi-step atomicity.

3) Volatile is less useful since java.util.atomic came about in 1.5.

 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Volatile and Snoopy Caches