Reputation: 5649
There is a method which is initializing three variables in a sequence :
public class Counter implements Runnable{
private int a;
private int b;
private volatile int c;
//Other code in class goes here
private void incrementCounter(int i){
a=10+i;
b=11+i;
c=12+i;
//some other code
}
}
The incrementCounter(int i) method is called by a thread, after the intialization of c variable, what will be the value of a,b and c in main memory and why ?
Upvotes: 2
Views: 198
Reputation: 19573
In short: The happens-before relationship created through a volatile read of a volatile write ensures that whoever reads the value of c
will also observe the changes to a
and b
.
A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field. [...] If hb(x, y) and hb(y, z), then hb(x, z).
https://docs.oracle.com/javase/specs/jls/se11/html/jls-17.html#jls-17.4.5
[...] because the happens-before relation is transitive, all actions of a thread prior to unlocking happen-before all actions subsequent to any thread locking that monitor.
[...]
Writes and reads of volatile fields have similar memory consistency effects as entering and exiting monitors[.]
https://download.java.net/java/GA/jdk14/docs/api/java.base/java/util/concurrent/package-summary.html
What's more, it also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.
https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html
Writing to a volatile field has the same memory effect as a monitor release, and reading from a volatile field has the same memory effect as a monitor acquire. In effect, because the new memory model places stricter constraints on reordering of volatile field accesses with other field accesses, volatile or not, anything that was visible to thread A when it writes to volatile field f becomes visible to thread B when it reads f.
https://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#synchronization
Same page goes on to construct an example very much like your own:
class VolatileExample {
int x = 0;
volatile boolean v = false;
public void writer() {
x = 42;
v = true;
}
public void reader() {
if (v == true) {
//uses x - guaranteed to see 42.
}
}
}
Finally, interesting pitfalls to be cautious about:
https://shipilev.net/blog/2016/close-encounters-of-jmm-kind/#pitfall-release-order-wrong
Upvotes: 1
Reputation: 8247
incrementCounter(int i) method is called by a thread, after the intialization of c variable, what will be the value of a,b and c in main memory and why?
I would rephrase your question as what would be the values of a,b and c as seen by Thread B after Thread A has completed its execution.
As per the below quote from JCIP, Thread B would see the updated values for both a
and b
as well along with c
, but it comes with a caution -
The visibility effects of volatile variables extend beyond the value of the volatile variable itself. When thread A writes to a volatile variable and subsequently thread B reads that same variable, the values of all variables that were visible to A prior to writing to the volatile variable become visible to B after reading the volatile variable. So from a memory visibility perspective, writing a volatile variable is like exiting a synchronized block and reading a volatile variable is like entering a synchronized block.
But it subsequently goes on saying that,
However, we do not recommend relying too heavily on volatile variables for visibility; code that relies on volatile variables for visibility of arbitrary state is more fragile and harder to understand than code that uses locking.
UPDATE: Removed the statements regarding atomicity of volatile variables as per Ralf's findings. Will revisit that section after doing some homework on the change history.
Upvotes: -1
Reputation: 16357
You should reason about visibility and ordering guarantees of the values of certain fields in terms of the Java Memory Model.
I'll assume that your question was meant to ask "What guarantees do I have for the values of a
, b
and c
as observed by other threads?"
In this case, in order to get a benefit out of the volatile
semantics, you need to have a volatile
read in another thread that sees a specific volatile
write. If that happens, the volatile
read synchronizes-with that volatile
write which happens-before the read, and the reading thread is guaranteed to see values for a
and b
no older than the values written in the thread where the observed value for c
was written.
P.S. When I say "no older", I am being informal, because the JMM goes to great lengths to avoid global time ordering of all actions. If we want to be formal, we can use the synchronization order, and define "no older" as not made visible by a volatile
write coming in the synchronization order before the one observed.
Upvotes: 5
Reputation: 27115
What will happen depends on the hardware platform and the JVM implementation. What must happen is specified by the the Java Language Specification (JLS).
The JLS says that some other thread U will be able to see all three updates when thread U reads c
.
More specifically, the JLS says an update to the volatile c
in thread T "synchronizes with" a read of c
in thread U. "Synchronizes with" means that everything that happened in thread T before T updated c
must become visible to thread U when thread U subsequently reads c
.
Note: The "synchronizes with" also goes by the name "happens before relationship", and that sometimes confuses new programmers. When somebody says, "An update of c
in one thread happens before a read of c
in another thread," then the newbie thinks that it means, "My thread T will update c
before my thread U reads it."
"Happens before" does not mean that at all. It only means that IF the update actually happens before the read, then...
When thread T and thread U both reach for c
without any controls, that's called a data race, and if the correct outcome of your program depends on which thread wins the race, then its up to you to use some synchronization means to insure that the right thread wins.
Upvotes: 1