I am only asking in threading perspective...probably answered many times but please help me to understand this.
With reference to post here Volatile Vs Static in java
asking a static variable value is also going to be one value for all threads, then why should we go for volatile? I found following example :
public class VolatileExample {
public static void main(String args[]) {
new ExampleThread("Thread 1 ").start();
new ExampleThread("Thread 2 ").start();
}
}
class ExampleThread extends Thread {
private static volatile int testValue = 1;
public ExampleThread(String str){
super(str);
}
public void run() {
for (int i = 0; i < 3; i++) {
try {
System.out.println(getName() + " : "+i);
if (getName().compareTo("Thread 1 ") == 0)
{
testValue++;
System.out.println( "Test Value T1: " + testValue);
}
if (getName().compareTo("Thread 2 ") == 0)
{
System.out.println( "Test Value T2: " + testValue);
}
Thread.sleep(1000);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
}
}
Output:
Thread 1 : 0
Test Value T1: 2
Thread 2 : 0
Test Value T2: 2
Thread 1 : 1
Test Value T1: 3
Thread 2 : 1
Test Value T2: 3
Thread 1 : 2
Test Value T1: 4
Thread 2 : 2
Test Value T2: 4
If I remove the static from the testValue, result obtained:
Thread 1 : 0
Test Value T1: 2
Thread 2 : 0
Test Value T2: 1
Thread 1 : 1
Test Value T1: 3
Thread 2 : 1
Test Value T2: 1
Thread 1 : 2
Test Value T1: 4
Thread 2 : 2
Test Value T2: 1
Why thread 2 is not reading the updated value? If it has to be made static , whats the use of volatile?
Can someone give link to a good example of volatile where that variable is not declare static.
Thanks
The problem is that the ++ is not atomic. The code should use AtomicInteger
instead. With the static
variable, both threads are trying to update the same value and the ++ is actually 3 operations: get, +1, and store. This means that there is a race condition between both of the threads and they are overwriting each other.
Why thread 2 is not reading the updated value? If it has to be made static , whats the use of volatile?
static
and volatile
do different things. static
makes the field associated with the class as opposed to the object instance. volatile
forces any read or write of the field to cross a memory barrier. This allows multiple threads to read and update a common field but this does not protected you from multiple operations. If you make the variable not be static then you would not need the volatile
since each thread would be working with it's own instance of the field.
You should use AtomicInteger
. This wraps a volatile int
but also provides special handling of increment operations:
private static AtomicInteger testValue = new AtomicInteger(1);
...
testValue.incrementAndGet();
Can someone give link to a good example of volatile where that variable is not declare static.
You would need a volatile
on a non-static field when it was shared by multiple threads. For example, if you moved the testValue
up into the VolatileExample
class and then passed the same instance of the VolatileExample
class into both threads so they could access testValue
.
The use of volatile
is to ensure that all threads see the same value at the same time. Essentially it is saying that this variable should never be cached.
It is difficult to demonstrate in code because cacheing strategies change from cpu to cpu and from JRE to JRE.
What volatile
is saying to the JRE is If you are ever tempted to cache this value because you think you could make the code run a little faster by doing so ... DONT! ... I know MUCH more about programming than you do and I know without a shadow of a doubt that if you do you will break my code..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With