In Java Concurrency In Practice, it says that
A write to a volatile field happens-before every subsequent read of
that same field
Does that mean if two threads try to simultaneously read and write to a volatile field, the JVM will ensure that the write operation precedes the read operation or would there be a race condition anyway ?
There would be a race condition. The outcome would depend on who gets there first:
If the write is first, the happens-before guarantees that the read will see the new value.
If the read is first, the happens-before with the most recent earlier write guarantees that the read will see the value of that write.
A happens-before relationship has an extremely specific meaning in the Java specification. Oracle provides an overview of what it means in their concurrency tutorial.
It's important to understand that the relationship is defined over time spent on the CPU. In other words, it has nothing to do with the initial order in which events occur: a write or a read could come first in your application.
It rather says that if the write is executed first, then the effects of that write will be visible to all threads before they execute subsequent read operations. It just provides memory consistency.
If the write to the volatile field happens before the read of that field, then volatile will guarantee that the read will be the latest value.
Note volatile does not guarantee atomicity, it guarantees visibility.
Related
The memory model is defined in 17.4. Memory Model.
The final field multi-threading guarantees are given in 17.5. final Field Semantics.
I don't understand why these are separate sections.
AFAIK both final and the memory model provide some guarantees.
And any real program execution must respect both guarantees.
But it's now clear whether the final guarantees work for the intermediate executions used to validate causality requirements in 17.4.8. Executions and Causality Requirements.
Another unclear moment is that 17.5.1. Semantics of final Fields defines a new "special" happens-before, which differs from the happens-before in the memory model:
This happens-before ordering does not transitively close with other happens-before orderings.
If these are the same happens-before, then the happens-before isn't a partial order anymore (because it isn't transitive).
I don't understand how this doesn't break things.
If these are different happens-before, then it's not clear what the one in 17.5. final Field Semantics does.
The happens-before in 17.4. Memory Model is used to restrict what a read can return:
Informally, a read r is allowed to see the result of a write w if there is no happens-before ordering to prevent that read.
But 17.5. final Field Semantics is a different section.
The special 'final field guarantees' part was a later add-on. Documentation sometimes follows the quirks of history - possibly, had the 'final field guarantee' issue been discovered prior to the first release of the JMM, the documentation would have been structured differently.
In other words, you're asking for 'why is this stuff in a separate chapter' and perhaps the answer is: "Because it was added in a later version of java, and therefore it was written at a completely different time; a new chapter is presumably the simplest way to add some more documentation". We're talking about decades ago at this point, of course.
§17.5 explains its purpose. Quote:
The usage model for final fields is a simple one: Set the final fields for an object in that object's constructor; and do not write a reference to the object being constructed in a place where another thread can see it before the object's constructor is finished. If this is followed, then when the object is seen by another thread, that thread will always see the correctly constructed version of that object's final fields. It will also see versions of any object or array referenced by those final fields that are at least as up-to-date as the final fields are.
In other words, in the distant past, you could do this:
Thread A:
Make a new object. The constructor is 'well behaved' 1
Communicate the ref to this new object to another thread. Possibly in an unsafe way.
Thread B:
The receiving thread gets the correct ref (either because you did it safely with synchronization, i.e. happens-before relationship set up properly, or because you did it unsafely, but the JMM does not guarantee that unsafe code fails to work: It may still work).
It calls a method of this object.
Said object witnesses a final-marked field that isn't initialized, because the initialization did occur in thread A, but no happens-before relationship exists, and re-ordering and other shenanigans means that this thread doesn't see it yet.
This is extremely annoying. Part of the point of immutable classes is that you can more or less print out the JMM and set it on fire. You just don't need to care about virtually every tricky rule in it if your system is an amalgamation of immutable types. Except, it didn't actually work out that way prior to the existence of §17.5
The JMM as a general principle is designed to give any JVM implementations as few 'handcuffs' as possible whilst making developing for the JVM as uncomplicated as possible. It's a fine line - for example, had the JMM simply stated: "The JVM is free to re-order whatever it wants at any time, and cache whatever it wants, at any time, for whatever duration it wants", then writing JVMs that run code quickly and according to spec would be 'easier' (JVM impls would be faster), but, writing multithreaded code that actually does what you intended it to becomes borderline impossible. On the flipside, the JMM could also have guaranteed that re-ordering in the JVM is impossible to observe regardless of circumstance or architecture. But then JVMs would be slow as molasses, see Python and its much maligned global interpreter lock.
The JMM tries to be the happy compromise. And §17.5 is written with the same spirit.
It basically says:
You CAN rely on the notion that any well-behaved construction means that final fields will just work out without having to worry about happens-before relationships whatsoever.
However, you CANNOT, at all, rely on HOW the JVM implements the guarantee. In particular, we have defined what you can exactly rely on in terms of Happens-Before, but it's not the same H-B that the rest of the JMM talks about. We guarantee you that well-behaved construction means final fields won't be an issue but that's as far as our guarantee goes: You cannot use this guarantee to then force other guarantees out of the JMM; you can't use this mechanism as a wonky way to establish H-B for other stuff, for example.
The JMM buys room to maneuver for JVM impls. Whether a JVM impl actually uses it, is up to the JVM implementor. In other words, a JVM implementor may well decide to implement §17.5 by using the same locking mechanisms it uses to guarantee the H-B stuff in §17.4, and thus effectively you can apply properties like 'H-B relationships are transitive'. The point of the JMM is partly to allow JVM impls to take some pretty drastically different approaches to how the guarantees it dictates are in fact guaranteed. That's because JVMs have to be written so that they can run code about as fast as native code could on a wide variety of hardware, whilst still being a target platform that isn't impossible to develop for.
Quite the tightrope walk. This is the primary underlying explanation for the JMM can be obtuse and bizarre at times.
[1] A 'well behaved' constructor:
Does not pass its own reference (this) to any code outside of its own class during construction.
Does not invoke any of its own instance methods that then read its own fields (or, especially problematic, which can be overridden by subclasses, whose implementation uses its own fields). Basically: Calling any non-final method is an instant "You are not well behaved" violation.
Does not send any object refs of things I wishes to store in fields to code in other classes during construction. Even if it has already assigned it to the final field before doing so.
From documentation page:
Package java.util.concurrent.atomic Description:
A small toolkit of classes that support lock-free thread-safe programming on single variables. In essence, the classes in this package extend the notion of volatile values, fields, and array elements to those that also provide an atomic conditional update operation of the form
boolean compareAndSet(expectedValue, updateValue);
With many options available in atomic package like
AtomicBoolean
AtomicInteger
AtomicLongArray
etc, can I use these AtomicXXX and slowly get rid of volatile variables in my legacy code?
EDIT:
Keep volatile for single write & multiple read operations in different threads (my conclusion after reading many articles), multi-writer, single-reader cases ( as per #erickson comments)
Use AtomicXXX for multiple updates & multiple reads among multiple threads to avoid synchronization. Provide atomicity to volatile variables.
My thought process has been changed with #ericksoncomments.volatile supports multiple write & single read` but can fail with multiple writes and multiple reads. I am confused on this concept.
Yes, an AtomicXXX instance provides the same visibility guarantees that you get from accessing a volatile field.
However, AtomicXXX do more than volatile fields, and accordingly, they are a bit more expensive to use. Specifically, they provide operations that are more like an optimized synchronized block than a volatile read or write. You increment-and-get, or compare-and-swap—multiple actions, atomically. Volatile variables don't provide any atomicity.
So, switching from volatile to AtomicXXX isn't necessarily a good move. Consider if it makes sense given how data are used, and perhaps do some profiling on a prototype to see what performance impact it will have.
I was trying to understand the use of volatile keyword in java. I understand it will write the data in main memory not in thread cache.
But is that really useful. I am using multi threading and
shouldn't I be using synchronized cause I don't want dirty reads to other threads. so at what exact situation volatile can be useful and most important to use?
Please give some example.
synchronized is much more expensive than plain volatile.
volatile is useful when you just need to read/write single variable and don't care about atomicity of complex structures.
synchronized is useful when you need to perform complex operations, update several variables or set one variable when compared another one and ensure the atomicity of such operation. Also it is used when doing higher level synchronization such as conditions, i.e. synchronized/wait/notify in java. But for that Lock/Condition can be used too.
For even better explanation about using volatile variables you can view the following link with JB Nizet's answer. It compliments well the answer posted by Zbynek and further explains the relation between volatile, atomic variables & complexity. Hope this helps.
My guess is that it would be similar with volatile keyword, which gives happened-before relation, visibility and atomic value assignment(in case of >32bit types as long) in Java. Is it?
(edit: my guess was that atomic attribute was similar to volatile, not nonatomic but turns out it wasn't anyway)
"Atomic" in Objective C, according to this article, is similar to a synchronized variable in Java, such that it cannot be changed by two threads at the same time. nonatomic is the opposite, meaning a variable that is not synchronized, and therefore could be changed by multiple threads simultaneously.
Regarding volatile, according to wikipedia:
The Java programming language also has the volatile keyword, but it is used for a somewhat different purpose. When applied to a field, the Java volatile guarantees that:
(In all versions of Java) There is a global ordering on the reads and writes to a volatile variable. This implies that every thread accessing a volatile field will read its current value before continuing, instead of (potentially) using a cached value. (However, there is no guarantee about the relative ordering of volatile reads and writes with regular reads and writes, meaning that it's generally not a useful threading construct.)
(In Java 5 or later) Volatile reads and writes establish a happens-before relationship, much like acquiring and releasing a mutex.
Using volatile may be faster than a lock, but it will not work in some situations. The range of situations in which volatile is effective was expanded in Java 5; in particular, double-checked locking now works correctly.
I know using volatile keyword in Java we get some kind of weak synchronization (It allows visibility updates but do not provide actual locking). Is there any situation where volatile should be given preference over actual locking in implementing concurrent programs. A somewhat similar question is there on SO which says volatile as a synchronization mechanism but that was tagged to C#.
If the shared state consists in a single field, and you don't use any get-and-set construct (like i++ for example) to assign it, then volatile is good enough. Most of the volatile usages can be replaced by the use of AtomicXxx types, though (which provide atomic get-and-set operations).
In short, you should prefer to avoid locks wherever they are not necessary since locks expose your program to deadlocks and deter performance by excluding concurrency from critical parts of code. So, whenever the situation permits, by all means rely on volatile; if all you additionally need is atomic two-step operations like compare-and-swap, use AtomicReference. Fall back to synchronized only for the scenarios where this is the only option. For example, if you need to lazily initialize a heavy object, you'll need locks to prevent double initialization—but again, not to fetch the already initialized instance (double-check idiom).
Volatile guarantees that all threads will see the last write of a variable by any other thread, that's it. There's no synchronization involved. If you synchronize both read and write method of an instance variable, then you don't have to make that variable volatile (all threads will see the most recent write).