Reputation: 1031
I have few doubts about volatile semantics.
Assume there are three threads T1, T2 and T3 and a single instance of the given class.
class Foo {
private int x = 1;
private int y = 2;
private int z = 3;
private volatile int w = 4;
private volatile int v = 5;
public void setX(int x) {
this.x = x;
}
public int getX() {
return this.x;
}
(...)
}
Let's say the following sequence of read/write actions occurs:
1. (T1) foo.getX(); // stored in a local memory of T1
2. (T1) foo.getY(); // stored in a local memory of T1
3. (T2) foo.setX(10);
4. (T2) foo.setY(20);
5. (T3) foo.getY(); // T3 may see 2 or 20, no guarantees if a write action from point 4 is visible to T3
6. (T3) foo.setZ(30);
7. (T3) foo.setW(40);
8. (T3) foo.setV(50);
9. (T1) foo.getW()
10. (T1) foo.getZ()
11. (T1) foo.getY()
12. (T1) foo.getX()
I know that it is guaranteed that T1 at point 9 will see a value set at point 7 and that T1 at point 10 will see a value set at point 6 (to be exact at least as up-to-date as this value).
But, are these statements true?
Please confirm that my understanding is correct.
Upvotes: 4
Views: 155
Reputation: 388
As long as your get/set operations ONLY get and set the variable, then all of your assumptions will be correct.
In Java variables are stored in memory. But the compiler (and runtime) will allow a variable to be stored temporarily in the CPU cache to allow quicker read and writes for the duration of an algorithm or section of code.
The downside to this caching is that when the Core is done with the variable it will write it back to memory as if it was only updated once. The other cores can't see the state of the variable while it was being used. To make it worse, there is no order guarantee as to WHEN it will be written back to memory.
By setting a variable as Volatile you are telling java that the variable is not allowed to be put into ANY caches. A read or write on the variable must occur in memory.
This means that Volatile will make single operations on the variable atomic. But it will also make long operations on the variable a WHOLE LOT SLOWER. So volatile is not a solution for getting a performance increase out of multi-threaded code.
Notably, an operation that requires more than one read or write is not atomic. For example i++ which is actually i = i + 1 could have the value of i changed before the write is completed.
If you need to guarantee that operations occur atomically you can use a lock or semtex (slow) or you can use a clever paradigm like Copy-On-Write (COW) to allow atomic reads and atomic writes.
Upvotes: 1