Related
We use volatile in one of our projects to maintain the same copy of variable accessed by different threads. My question is whether it is alright to use volatile with static. The compiler does not give any errors but I don't understand the reason of using both.
Short of reading the memory model specification, I recommend you read http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html. It's written by one of the JMM authors and should answer your question. Thinking of memory reads and writes in terms of the happens-before clause is also helpful; the JMM for Java 5 onwards adds happens-before semantics to volatile.
Specifically, when you read a volatile variable from one thread, all writes up to and including the write to that volatile variable from other threads are now visible to that one thread.
And, yes, you can use static with volatile. They do different things.
In Java, volatile has a similar general meaning as it does in C. The Java Memory Model (see the excellent link in ide's answer) allows threads to "see" a different value at the same time for variables marked as non-volatile. For example:
Thread a:
n = 1;
// wait...
n = 2;
Threads B and C:
while (true) {
System.out.println(name + ": " + n);
}
This output is allowed to happen (note that you're not guaranteed to strictly alternate between B and C, I'm just trying to show the "changeover" of B and C here):
C: 1
B: 1
C: 2
B: 1
C: 2
B: 2
This is entirely separate from the lock taken by println; thread B is allowed to see n as 1 even after C finds out that it's 2. There are a variety of very good reasons for this that I can't pretend to fully understand, many pertaining to speed, and some pertaining to security.
If it's volatile, you're guaranteed (apart from the println's locking, which I'll ignore for the moment) that B and C will both "simultaneously" see the new value of B as soon as it is sent.
You can use volatile with static because they affect different things. volatile causes changes a variable to be "replicated" to all threads that use that variable before they use it, while static shares a single variable across all classes that use that variable. (This can be rather confusing to people new to threading in Java, because every Thread happens to be implemented as a class.)
volatile means that the variable changes at runtime and that the compiler should not cache its value for any reason.
This is only really a problem when sharing the variable amongst threads, you don't want a thread working with stale data, so the compiler should never cache the value of a volatile variable reference.
Consider a scenario when two thread (Thread1 and Thread2) are accessing same variable 'mObject' with value 1.
when a Thread1 runs, it doesn't expect other threads to modify the variable 'mObject'. In this scenario the Thread1 caches the variable 'mObject' with value 1.
And if the Thread2 modify the value of 'mObject' to 2, still the Thread1 would be refering the mObject value as 1 since it did caching.
To avoid this caching we should to declare the variable as
private volatile int mObject;
in this scenarion the Thread1 will be getting updated value of mObject
Small elaboration, but the volatile keyword isn't just for for memory visibility. Before Java ver 1.5 was released the volatile keyword declared that the field will get the most recent value of the object by hitting main memory each time for reads and flushing for writes.
In the latest Java versions, the volatile keyword says two very important things:
Don't worry about how but know that when reading a volatile field
you will always have the most up to date value.
A compiler cannot reorder a volatile read/write as to maintain program order.
Check it out for more Java volatile examples.
The Java volatile keyword is used to mark a Java variable as "being stored in main memory". More precisely that means, that every read of a volatile variable will be read from the computer's main memory, and not from the CPU cache, and that every write to a volatile variable will be written to main memory, and not just to the CPU cache. The value of an attribute is not cached thread-locally, and is always read from the "main memory".
Overcoming the data inconsistency problem is the advantage but reading from and writing to main memory is more expensive than accessing the CPU cache. Hence, if there are no specific requirements it is never recommended to use volatile keywords.
class Test
{
static int var=5;
}
In the above example, assume that two threads are working on the same class. Both threads run on different processors where each thread has its local copy of var. If any thread modifies its value, the change will not reflect in the original one in the main memory. It leads to data inconsistency because the other thread is not aware of the modified value.
class Test
{
static volatile int var =5;
}
In the above example, the value of a volatile variable will never be stored in the cache. All read and write will be done from and to the main memory.
I read the below program and answer in a blog.
int x = 0;
boolean bExit = false;
Thread 1 (not synchronized)
x = 1;
bExit = true;
Thread 2 (not synchronized)
if (bExit == true)
System.out.println("x=" + x);
is it possible for Thread 2 to print “x=0”?
Ans : Yes ( reason : Every thread has their own copy of variables. )
how do you fix it?
Ans: By using make both threads synchronized on a common mutex or make both variable volatile.
My doubt is : If we are making the 2 variable as volatile then the 2 threads will share the variables from the main memory. This make a sense, but in case of synchronization how it will be resolved as both the thread have their own copy of variables.
Please help me.
This is actually more complicated than it seems. There are several arcane things at work.
Caching
Saying "Every thread has their own copy of variables" is not exactly correct. Every thread may have their own copy of variables, and they may or may not flush these variables into the shared memory and/or read them from there, so the whole thing is non-deterministic. Moreover, the very term flushing is really implementation-dependent. There are strict terms such as memory consistency, happens-before order, and synchronization order.
Reordering
This one is even more arcane. This
x = 1;
bExit = true;
does not even guarantee that Thread 1 will first write 1 to x and then true to bExit. In fact, it does not even guarantee that any of these will happen at all. The compiler may optimize away some values if they are not used later. The compiler and CPU are also allowed to reorder instructions any way they want, provided that the outcome is indistinguishable from what would happen if everything was really in program order. That is, indistinguishable for the current thread! Nobody cares about other threads until...
Synchronization comes in
Synchronization does not only mean exclusive access to resources. It is also not just about preventing threads from interfering with each other. It's also about memory barriers. It can be roughly described as each synchronization block having invisible instructions at the entry and exit, the first one saying "read everything from the shared memory to be as up-to-date as possible" and the last one saying "now flush whatever you've been doing there to the shared memory". I say "roughly" because, again, the whole thing is an implementation detail. Memory barriers also restrict reordering: actions may still be reordered, but the results that appear in the shared memory after exiting the synchronized block must be identical to what would happen if everything was indeed in program order.
All that only works, of course, only if both blocks use the same locking object.
The whole thing is described in details in Chapter 17 of the JLS. In particular, what's important is the so-called "happens-before order". If you ever see in the documentation that "this happens-before that", it means that everything the first thread does before "this" will be visible to whoever does "that". This may even not require any locking. Concurrent collections are a good example: one thread puts there something, another one reads that, and that magically guarantees that the second thread will see everything the first thread did before putting that object into the collection, even if those actions had nothing to do with the collection itself!
Volatile variables
One last warning: you better give up on the idea that making variables volatile will solve things. In this case maybe making bExit volatile will suffice, but there are so many troubles that using volatiles can lead to that I'm not even willing to go into that. But one thing is for sure: using synchronized has much stronger effect than using volatile, and that goes for memory effects too. What's worse, volatile semantics changed in some Java version so there may exist some versions that still use the old semantics which was even more obscure and confusing, whereas synchronized always worked well provided you understand what it is and how to use it.
Pretty much the only reason to use volatile is performance because synchronized may cause lock contention and other troubles. Read Java Concurrency in Practice to figure all that out.
Q & A
1) You wrote "now flush whatever you've been doing there to the shared
memory" about synchronized blocks. But we will see only the variables
that we access in the synchronize block or all the changes that the
thread call synchronize made (even on the variables not accessed in the
synchronized block)?
Short answer: it will "flush" all variables that were updated during the synchronized block or before entering the synchronized block. And again, because flushing is an implementation detail, you don't even know whether it will actually flush something or do something entirely different (or doesn't do anything at all because the implementation and the specific situation already somehow guarantee that it will work).
Variables that wasn't accessed inside the synchronized block obviously won't change during the execution of the block. However, if you change some of those variables before entering the synchronized block, for example, then you have a happens-before relationship between those changes and whatever happens in the synchronized block (the first bullet in 17.4.5). If some other thread enters another synchronized block using the same lock object then it synchronizes-with the first thread exiting the synchronized block, which means that you have another happens-before relationship here. So in this case the second thread will see the variables that the first thread updated prior to entering the synchronized block.
If the second thread tries to read those variables without synchronizing on the same lock, then it is not guaranteed to see the updates. But then again, it isn't guaranteed to see the updates made inside the synchronized block as well. But this is because of the lack of the memory-read barrier in the second thread, not because the first one didn't "flush" its variables (memory-write barrier).
2) In this chapter you post (of JLS) it is written that: "A write to a
volatile field (§8.3.1.4) happens-before every subsequent read of that
field." Doesn't this mean that when the variable is volatile you will
see only changes of it (because it is written write happens-before
read, not happens-before every operation between them!). I mean
doesn't this mean that in the example, given in the description of the
problem, we can see bExit = true, but x = 0 in the second thread if
only bExit is volatile? I ask, because I find this question here: http://java67.blogspot.bg/2012/09/top-10-tricky-java-interview-questions-answers.html
and it is written that if bExit is volatile the program is OK. So the
registers will flush only bExits value only or bExits and x values?
By the same reasoning as in Q1, if you do bExit = true after x = 1, then there is an in-thread happens-before relationship because of the program order. Now since volatile writes happen-before volatile reads, it is guaranteed that the second thread will see whatever the first thread updated prior to writing true to bExit. Note that this behavior is only since Java 1.5 or so, so older or buggy implementations may or may not support this. I have seen bits in the standard Oracle implementation that use this feature (java.concurrent collections), so you can at least assume that it works there.
3) Why monitor matters when using synchronized blocks about memory
visibility? I mean when try to exit synchronized block aren't all
variables (which we accessed in this block or all variables in the
thread - this is related to the first question) flushed from registers
to main memory or broadcasted to all CPU caches? Why object of
synchronization matters? I just cannot imagine what are relations and
how they are made (between object of synchronization and memory).
I know that we should use the same monitor to see this changes, but I
don't understand how memory that should be visible is mapped to
objects. Sorry, for the long questions, but these are really
interesting questions for me and it is related to the question (I
would post questions exactly for this primer).
Ha, this one is really interesting. I don't know. Probably it flushes anyway, but Java specification is written with high abstraction in mind, so maybe it allows for some really weird hardware where partial flushes or other kinds of memory barriers are possible. Suppose you have a two-CPU machine with 2 cores on each CPU. Each CPU has some local cache for every core and also a common cache. A really smart VM may want to schedule two threads on one CPU and two threads on another one. Each pair of the threads uses its own monitor, and VM detects that variables modified by these two threads are not used in any other threads, so it only flushes them as far as the CPU-local cache.
See also this question about the same issue.
4) I thought that everything before writing a volatile will be up to
date when we read it (moreover when we use volatile a read that in
Java it is memory barrier), but the documentation don't say this.
It does:
17.4.5.
If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).
If hb(x, y) and hb(y, z), then hb(x, z).
A write to a volatile field (§8.3.1.4) happens-before every subsequent
read of that field.
If x = 1 comes before bExit = true in program order, then we have happens-before between them. If some other thread reads bExit after that, then we have happens-before between write and read. And because of the transitivity, we also have happens-before between x = 1 and read of bExit by the second thread.
5) Also, if we have volatile Person p does we have some dependency
when we use p.age = 20 and print(p.age) or have we memory barrier in
this case(assume age is not volatile) ? - I think - No
You are correct. Since age is not volatile, then there is no memory barrier, and that's one of the trickiest things. Here is a fragment from CopyOnWriteArrayList, for example:
Object[] elements = getArray();
E oldValue = get(elements, index);
if (oldValue != element) {
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len);
newElements[index] = element;
setArray(newElements);
} else {
// Not quite a no-op; ensures volatile write semantics
setArray(elements);
Here, getArray and setArray are trivial setter and getter for the array field. But since the code changes elements of the array, it is necessary to write the reference to the array back to where it came from in order for the changes to the elements of the array to become visible. Note that it is done even if the element being replaced is the same element that was there in the first place! It is precisely because some fields of that element may have changed by the calling thread, and it's necessary to propagate these changes to future readers.
6) And is there any happens before 2 subsequent reads of volatile
field? I mean does the second read will see all changes from thread
which reads this field before it(of course we will have changes only
if volatile influence visibility of all changes before it - which I am
a little confused whether it is true or not)?
No, there is no relationship between volatile reads. Of course, if one thread performs a volatile write and then two other thread perform volatile reads, they are guaranteed to see everything at least up to date as it was before the volatile write, but there is no guarantee of whether one thread will see more up-to-date values than the other. Moreover, there is not even strict definition of one volatile read happening before another! It is wrong to think of everything happening on a single global timeline. It is more like parallel universes with independent timelines that sometimes sync their clocks by performing synchronization and exchanging data with memory barriers.
It depends on the implementation which decides if threads will keep a copy of the variables in their own memory. In case of class level variables threads have a shared access and in case of local variables threads will keep a copy of it. I will provide two examples which shows this fact , please have a look at it.
And in your example if I understood it correctly your code should look something like this--
package com.practice.multithreading;
public class LocalStaticVariableInThread {
static int x=0;
static boolean bExit = false;
public static void main(String[] args) {
Thread t1=new Thread(run1);
Thread t2=new Thread(run2);
t1.start();
t2.start();
}
static Runnable run1=()->{
x = 1;
bExit = true;
};
static Runnable run2=()->{
if (bExit == true)
System.out.println("x=" + x);
};
}
Output
x=1
I am getting this output always. It is because the threads share the variable and the when it is changed by one thread other thread can see it. But in real life scenarios we can never say which thread will start first, since here the threads are not doing anything we can see the expected result.
Now take this example--
Here if you make the i variable inside the for-loop` as static variable then threads won t keep a copy of it and you won t see desired outputs, i.e. the count value will not be 2000 every time even if u have synchronized the count increment.
package com.practice.multithreading;
public class RaceCondition2Fixed {
private int count;
int i;
/*making it synchronized forces the thread to acquire an intrinsic lock on the method, and another thread
cannot access it until this lock is released after the method is completed. */
public synchronized void increment() {
count++;
}
public static void main(String[] args) {
RaceCondition2Fixed rc= new RaceCondition2Fixed();
rc.doWork();
}
private void doWork() {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
for ( i = 0; i < 1000; i++) {
increment();
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for ( i = 0; i < 1000; i++) {
increment();
}
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
/*if we don t use join then count will be 0. Because when we call t1.start() and t2.start()
the threads will start updating count in the spearate threads, meanwhile the main thread will
print the value as 0. So. we need to wait for the threads to complete. */
System.out.println(Thread.currentThread().getName()+" Count is : "+count);
}
}
Note
By saying that a memory access can (or cannot) be reordered I meand that it can be
reordered either by the compiler when emitting byte code byte or by the JIT when emitting
machine code or by the CPU when executing out of order (eventually requiring barriers to prevent this) with respect to any other memory access.
If often read that accesses to volatile variables cannot be reordered due to the Happens-Before relationship (HBR).
I found that an HBR exists between every two consecutive (in program order) actions of
a given thread and yet they can be reordered.
Also a volatile access HB only with accesses on the same variable/field.
What I thinks makes the volatile not reorderable is this
A write to a volatile field (§8.3.1.4) happens-before every subsequent read [of any thread]
of that field.
If there are others threads a reordering of the variables will becomes visible as in this
simple example
volatile int a, b;
Thread 1 Thread 2
a = 1; while (b != 2);
b = 2; print(a); //a must be 1
So is not the HBR itself that prevent the ordering but the fact that volatile extends this relationship with other threads, the presence of other threads is the element that prevent reordering.
If the compiler could prove that a reordering of a volatile variable would not change the
program semantic it could reorder it even if there is an HBR.
If a volatile variable is never accessed by other threads than its accesses
could be reordered
volatile int a, b, c;
Thread 1 Thread 2
a = 1; while (b != 2);
b = 2; print(a); //a must be 1
c = 3; //c never accessed by Thread 2
I think c=3 could very well be reordered before a=1, this quote from the specs
confirm this
It should be noted that the presence of a happens-before relationship between
two actions does not necessarily imply that they have to take place in that order
in an implementation. If the reordering produces results consistent with a legal
execution, it is not illegal.
So I made these simple java programs
public class vtest1 {
public static volatile int DO_ACTION, CHOOSE_ACTION;
public static void main(String[] args) {
CHOOSE_ACTION = 34;
DO_ACTION = 1;
}
}
public class vtest2 {
public static volatile int DO_ACTION, CHOOSE_ACTION;
public static void main(String[] args) {
(new Thread(){
public void run() {
while (DO_ACTION != 1);
System.out.println(CHOOSE_ACTION);
}
}).start();
CHOOSE_ACTION = 34;
DO_ACTION = 1;
}
}
In both cases both fields are marked as volatile and accessed with putstatic.
Since these are all the information the JIT has1, the machine code would be identical,
thus the vtest1 accesses will not be optimized2.
My question
Are volatile accesses really never reordered by specification or they could be3, but this is never done in practice?
If volatile accesses can never be reordered, what parts of the specs say so? and would this means that all volatile accesses are executed and seen in program order by the CPUs?
1Or the JIT can known that a field will never be accessed by other thread? If yes, how?.
2Memory barriers will be present for example.
3For example if no other threads are involved.
What the JLS says (from JLS-8.3.1.4. volatile Fields) is, in part, that
The Java programming language provides a second mechanism, volatile fields, that is more convenient than locking for some purposes.
A field may be declared volatile, in which case the Java Memory Model ensures that all threads see a consistent value for the variable (§17.4).
Which means the access may be reordered, but the results of any reordering must eventually be consistent (when accessed by another thread) with the original order. A field in a single threaded application wouldn't need locking (from volatile or synchronization).
The Java memory model provides sequential consistency (SC) for correctly synchronized programs. SC in simple terms means that if all possible executions of some program, can be explained by different executions in which all memory actions are executed in some sequential order and this order is consistent with the program order (PO) of each of the threads, then this program is consistent with these sequential executions; so it is sequential consistent (hence the name).
What this effectively means that the JIT/CPU/memory subsystem can reorder volatile writes and reads as much as it wants as long as there exists a sequential execution that could also explain the outcome of the actual execution. So the actual execution isn't that important.
If we look at the following example:
volatile int a, b, c;
Thread 1 Thread 2
a = 1; while (c != 1);
b = 1; print(b);
c = 1;
There is a happens before relation between a=1 and b=2 (PO), and a happens before relation between c=2 and c=3 (PO) and a happens before relation c=1 and c!=0 (Volatile variable rule) and a happens before relation between c!=0 and print(b) (PO).
Since the happens before relation is transitive, there is a happens before relation between a=1 and print(b). So in that sense, it can't be reordered. However, there is nobody to prove that a reordering happened, so it can still be reordered.
I'm going to be using notation from JLS §17.4.5.
In your second example, (if you'll excuse my loose notation) you have
Thread 1 ordering:
hb(a = 1, b = 2)
hb(b = 2, c = 3)
Volatile guarantees:
hb(b = 2, b != 2)
hb(a = 1, access a for print)
Thread 2 ordering:
hb(while(b != 2);, print(a))
and we have (emphasis mine)
More specifically, if two actions share a happens-before relationship,
they do not necessarily have to appear to have happened in that order
to any code with which they do not share a happens-before
relationship. Writes in one thread that are in a data race with reads
in another thread may, for example, appear to occur out of order to
those reads.
There is no happens-before relationship between c=3 and Thread 2. The implementation is free to reorder c=3 to its heart's content.
From 17.4. Memory Model of JLS
The memory model describes possible behaviors of a program. An implementation is free to produce any code it likes, as long as all resulting executions of a program produce a result that can be predicted by the memory model.
This provides a great deal of freedom for the implementor to perform a myriad of code transformations, including the reordering of actions and removal of unnecessary synchronization.
In the oracle Java documentation located here, the following is said:
Atomic actions cannot be interleaved, so they can be used without fear of thread interference. However, this does not eliminate all need to synchronize atomic actions, because memory consistency errors are still possible. Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable. This means that changes to a volatile variable are always visible to other threads. 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.
It also says:
Reads and writes are atomic for reference variables and for most
primitive variables (all types except long and double).
Reads and writes are atomic for all variables declared volatile (including long
and double variables).
I have two questions regarding these statements:
"Using volatile variables reduces the risk of memory consistency errors" - What do they mean by "reduces the risk", and how is a memory consistency error still possible when using volatile?
Would it be true to say that the only effect of placing volatile on a non-double, non-long primitive is to enable the "happens-before" relationship with subsequent reads from other threads? I ask this since it seems that those variables already have atomic reads.
What do they mean by "reduces the risk"?
Atomicity is one issue addressed by the Java Memory Model. However, more important than Atomicity are the following issues:
memory architecture, e.g. impact of CPU caches on read and write operations
CPU optimizations, e.g. reordering of loads and stores
compiler optimizations, e.g. added and removed loads and stores
The following listing contains a frequently used example. The operations on x and y are atomic. Still, the program can print both lines.
int x = 0, y = 0;
// thread 1
x = 1
if (y == 0) System.out.println("foo");
// thread 2
y = 1
if (x == 0) System.out.println("bar");
However, if you declare x and y as volatile, only one of the two lines can be printed.
How is a memory consistency error still possible when using volatile?
The following example uses volatile. However, updates might still get lost.
volatile int x = 0;
// thread 1
x += 1;
// thread 2
x += 1;
Would it be true to say that the only effect of placing volatile on a non-double, non-long primitive is to enable the "happens-before" relationship with subsequent reads from other threads?
Happens-before is often misunderstood. The consistency model defined by happens-before is weak and difficult to use correctly. This can be demonstrated with the following example, that is known as Independent Reads of Independent Writes (IRIW):
volatile int x = 0, y = 0;
// thread 1
x = 1;
// thread 2
y = 1;
// thread 3
if (x == 1) System.out.println(y);
// thread 4
if (y == 1) System.out.println(x);
Only with happens-before, two 0s would be valid result. However, that's apparently counter-intuitive. For that reason, Java provides a stricter consistency model, that forbids this relativity issue, and that is known as sequential consistency. You can find it in sections §17.4.3 and §17.4.5 of the Java Language Specification. The most important part is:
A program is correctly synchronized if and only if all sequentially consistent executions are free of data races. If a program is correctly synchronized, then all executions of the program will appear to be sequentially consistent (§17.4.3).
That means, volatile gives you more than happens-before. It gives you sequential consistency if used for all conflicting accesses (§17.4.3).
The usual example:
while(!condition)
sleep(10);
if condition is volatile, this behaves as expected. If it is not, the compiler is allowed to optimize this to
if(!condition)
for(;;)
sleep(10);
This is completely orthogonal to atomicity: if condition is of a hypothetical integer type that is not atomic, then the sequence
thread 1 writes upper half to 0
thread 2 reads upper half (0)
thread 2 reads lower half (0)
thread 1 writes lower half (1)
can happen while the variable is updated from a nonzero value that just happens to have a lower half of zero to a nonzero value that has an upper half of zero; in this case, thread 2 reads the variable as zero. The volatile keyword in this case makes sure that thread 2 really reads the variable instead of using its local copy, but it does not affect timing.
Third, atomicity does not protect against
thread 1 reads value (0)
thread 2 reads value (0)
thread 1 writes incremented value (1)
thread 2 writes incremented value (1)
One of the best ways to use atomic volatile variables are the read and write counters of a ring buffer:
thread 1 looks at read pointer, calculates free space
thread 1 fills free space with data
thread 1 updates write pointer (which is `volatile`, so the side effects of filling the free space are also committed before)
thread 2 looks at write pointer, calculates amount of data received
...
Here, no lock is needed to synchronize the threads, atomicity guarantees that the read and write pointers will always be accessed consistently and volatile enforces the necessary ordering.
For question 1, the risk is only reduced (and not eliminated) because volatile only applies to a single read/write operation and not more complex operations such as increment, decrement, etc.
For question 2, the effect of volatile is to make changes immediately visible to other threads. As the quoted passage states "this does not eliminate all need to synchronize atomic actions, because memory consistency errors are still possible." Simply because reads are atomic does not mean that they are thread safe. So establishing a happens before relationship is almost a (necessary) side-effect of guaranteeing memory consistency across threads.
Ad 1: With a volatile variable, the variable is always checked against a master copy and all threads see a consistent state. But if you use that volatility variable in a non-atomic operation writing back the result (say a = f(a)) then you might still create a memory inconsistency. That's how I would understand the remark "reduces the risk". A volatile variable is consistent at the time of read, but you still might need to use a synchronize.
Ad 2: I don't know. But: If your definition of "happens before" includes the remark
This means that changes to a volatile variable are always visible to other threads. 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.
I would not dare to rely on any other property except that volatile ensures this. What else do you expect from it?!
Assume that you have a CPU with a CPU cache or CPU registers. Independent from your CPU architecture in terms of number of cores it has, volatile does NOT guarantee you a perfect inconsistency. The only way to achieve this is to use synchronized or atomic references with a performance price.
For example you have multiple threads (Thread A & Thread B) working on a shared data. Assume that Thread A wants to update the shared data and it's is started .For performance reasons, Thread A's stack was moved to CPU cache or registers. Then Thread A updated the shared data. But the problem with those places is that actually they don't flush back the updated value to the main memory immediately. This is where inconsistency's offered because up to the flash back operation, Thread B might have wanted to play with the same data, which would have taken it from the main memory - yet unupdated value.
If you use volatile all the operations will be perfomed on the main memory so you don't have a flush back latency. But, this time you may suffer from thread pipeline. In the middle of write operation (composed of number of atomic operations), Thread B may have been executed by the os to perform a read operation and that's it! Thread B will read the unupdated value again. That's why it's said it reduces the risk.
Hope you got it.
when coming to concurrency, you might want to ensure 2 things:
atomic operations: a set of operations is atomic - this is usually achieved with
"synchronized" (higher level constructs). Also with volatile for instance for read/write on long and double.
visibility: a thread B sees a modification made by a thread A. Even if an operation is atomic, like a write to an int variable, a second thread can still see a non-up-to-date value of the variable, due to processor caches. Putting a variable as volatile ensures that the second thread does see the up-to-date value of that variable. More than that, it ensures that the second thread sees an up-to-date value of ALL the variables written by the first thread before the write to the volatile variable.
We use volatile in one of our projects to maintain the same copy of variable accessed by different threads. My question is whether it is alright to use volatile with static. The compiler does not give any errors but I don't understand the reason of using both.
Short of reading the memory model specification, I recommend you read http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html. It's written by one of the JMM authors and should answer your question. Thinking of memory reads and writes in terms of the happens-before clause is also helpful; the JMM for Java 5 onwards adds happens-before semantics to volatile.
Specifically, when you read a volatile variable from one thread, all writes up to and including the write to that volatile variable from other threads are now visible to that one thread.
And, yes, you can use static with volatile. They do different things.
In Java, volatile has a similar general meaning as it does in C. The Java Memory Model (see the excellent link in ide's answer) allows threads to "see" a different value at the same time for variables marked as non-volatile. For example:
Thread a:
n = 1;
// wait...
n = 2;
Threads B and C:
while (true) {
System.out.println(name + ": " + n);
}
This output is allowed to happen (note that you're not guaranteed to strictly alternate between B and C, I'm just trying to show the "changeover" of B and C here):
C: 1
B: 1
C: 2
B: 1
C: 2
B: 2
This is entirely separate from the lock taken by println; thread B is allowed to see n as 1 even after C finds out that it's 2. There are a variety of very good reasons for this that I can't pretend to fully understand, many pertaining to speed, and some pertaining to security.
If it's volatile, you're guaranteed (apart from the println's locking, which I'll ignore for the moment) that B and C will both "simultaneously" see the new value of B as soon as it is sent.
You can use volatile with static because they affect different things. volatile causes changes a variable to be "replicated" to all threads that use that variable before they use it, while static shares a single variable across all classes that use that variable. (This can be rather confusing to people new to threading in Java, because every Thread happens to be implemented as a class.)
volatile means that the variable changes at runtime and that the compiler should not cache its value for any reason.
This is only really a problem when sharing the variable amongst threads, you don't want a thread working with stale data, so the compiler should never cache the value of a volatile variable reference.
Consider a scenario when two thread (Thread1 and Thread2) are accessing same variable 'mObject' with value 1.
when a Thread1 runs, it doesn't expect other threads to modify the variable 'mObject'. In this scenario the Thread1 caches the variable 'mObject' with value 1.
And if the Thread2 modify the value of 'mObject' to 2, still the Thread1 would be refering the mObject value as 1 since it did caching.
To avoid this caching we should to declare the variable as
private volatile int mObject;
in this scenarion the Thread1 will be getting updated value of mObject
Small elaboration, but the volatile keyword isn't just for for memory visibility. Before Java ver 1.5 was released the volatile keyword declared that the field will get the most recent value of the object by hitting main memory each time for reads and flushing for writes.
In the latest Java versions, the volatile keyword says two very important things:
Don't worry about how but know that when reading a volatile field
you will always have the most up to date value.
A compiler cannot reorder a volatile read/write as to maintain program order.
Check it out for more Java volatile examples.
The Java volatile keyword is used to mark a Java variable as "being stored in main memory". More precisely that means, that every read of a volatile variable will be read from the computer's main memory, and not from the CPU cache, and that every write to a volatile variable will be written to main memory, and not just to the CPU cache. The value of an attribute is not cached thread-locally, and is always read from the "main memory".
Overcoming the data inconsistency problem is the advantage but reading from and writing to main memory is more expensive than accessing the CPU cache. Hence, if there are no specific requirements it is never recommended to use volatile keywords.
class Test
{
static int var=5;
}
In the above example, assume that two threads are working on the same class. Both threads run on different processors where each thread has its local copy of var. If any thread modifies its value, the change will not reflect in the original one in the main memory. It leads to data inconsistency because the other thread is not aware of the modified value.
class Test
{
static volatile int var =5;
}
In the above example, the value of a volatile variable will never be stored in the cache. All read and write will be done from and to the main memory.