• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Does volatile provide read-write atomicity?

 
marwen Bakkar
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I'm still not 100% sure about this and I'd like some input. When you read about the volatile keyword semantics you learn about its visibility effects. You also learn that volatile does not provide atomicity, but this observation is always made in the context of compound actions: you can't make n actions transactional using volatile like you can do so with synchronized.

But does volatile give us read-write atomicity too, or should it only be used with types that inherently have this property like boolean? (which means some variables are read-write atomic, and some others aren't, like 64 bit values I think)
I'd say it yes does, that is, volatile applied to any variable type makes that variable read and write atomic. The reason I think this is because in order to ensure visibility, volatile must establish the happens-before relationship between thread A writing to the volatile and other threads subsequently reading from it, which is the very definition of atomicity :

Operations A and B are atomic with respect to each other if, from the perspective of a thread executing A, when
another thread executes B, either all of B has executed or none of it has. An atomic operation is one that is atomic with
respect to all operations, including itself, that operate on the same state. - Java Concurrency in Practice.

To put it simply, I want to know if a write to a volatile variable, no matter what it's type, can happen concurrently or not.

Thanks.
 
Raymond Tong
Ranch Hand
Posts: 255
2
IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Do you mean read-modify-write is atomic for volatile variable? like above?
 
marwen Bakkar
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nope. That's a compound action that requires compare and swap (or locking). I mean when one thread is performing



can another thread be writing to a at the same time, no matter the type of a?
 
Chris Hurst
Ranch Hand
Posts: 443
3
C++ Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If its volatile one will happen before the other but you don't know which one , just a plain old data race.

Without the volatile you could argue they could write at the same time, more efficiently but still end up with a data race.

basically if you want to avoid race conditions use a lock (of some form or CAS)


32 bit values are read write atomic , 64 bit references if you have them ;-) are also (just the reference)
 
Vladimir Ozerov
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is one and only one rule for volatile variables: "A write to a volatile field happens-before every subsequent read of that same field."
This is it. It only guarantees that the reader will always see actual value of the variable in case it is performed after write from another thread.
There is no word about writer-wirter collaboration.
 
Chris Hurst
Ranch Hand
Posts: 443
3
C++ Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It only guarantees that the reader will always see actual value of the variable in case


Strictly it guarantees more , pre JSR 133 this was true, post new memory model it guarantees effectively the same as a monitor release and establishes happens before order such that non volatile writes pre the volatile write have happened effectively for the volatile reader. It's not just an effective cache flush of a 32 bit value. This is particularly important when you consider things like the double checked locking idiom ... http://en.wikipedia.org/wiki/Double-checked_locking

Better explanation here under ... What does volatile do

http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#volatile
 
marwen Bakkar
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


It doesn't address this specific question but thanks for the excellent link

I think that when in a doubt the thing to do is to use AtomicReference.
 
Henry Wong
author
Marshal
Pie
Posts: 21221
81
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

On a 32 bit JVM, all read or writes (single load or store) are almost always atomic -- the exceptions for longs and doubles. On a 64 bit JVM, there are no exceptions.

With volatile, a few things changes. The variable won't be cached. The memory model will restrict what the JVM can do with the load and store ordering. And finally, on a 32 bit JVM, load or store, for longs and doubles, are now guaranteed to be atomic. For this last case, the JVM will use an internal lock to make that guarantee.

Henry
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:With volatile [...] on a 32 bit JVM, load or store, for longs and doubles, are now guaranteed to be atomic. For this last case, the JVM will use an internal lock to make that guarantee.

To be fair, this was always "guaranteed" according to the JLS. It just didn't actually work reliably until JDK 5 or so. I think they may have back-ported a fix into 1.4 as well.
 
marwen Bakkar
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks!
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic