I wrote following code to understand the volatile concept in java but the output seems to be confusing rather than clarifying the concept. Corrections, clarifications and feedback are welcomed and appreciated.
package threading;
public class UnSyncRead {
//volatile static int value = 987;
static int value = 987;
public static void main(String[] args) {
ThreadEx4 t = new ThreadEx4(value);
t.start();
for(int i=0;i<4;i++) {
Thread thread = new Thread( new ThreadEx3(value));
thread.start();
}
}
}
class ThreadEx3 implements Runnable{
private int i;
public ThreadEx3(int i) {
this.i=i;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getId()+ " "+Thread.currentThread().getName()+" "+ " inside "+i);
}
}
class ThreadEx4 extends Thread{
private int i;
public ThreadEx4(int i) {
this.i=i;
}
public void run() {
++i;
System.out.println("changed the value to "+i);
}
}
This program gives the following output
changed the value to 988
12 Thread-1 inside 987
13 Thread-2 inside 987
14 Thread-3 inside 987
15 Thread-4 inside 987
but if I modify the code to make value
variable volatile
by doing following change and running the code.
public class UnSyncRead {
volatile static int value = 987;
//static int value = 987;
public static void main(String[] args) {
ThreadEx4 t = new ThreadEx4(value);
t.start();
for(int i=0;i<4;i++) {
Thread thread = new Thread( new ThreadEx3(value));
thread.start();
}
}
}
I get following output which is exactly same when I ran it without volatile keyword.
changed the value to 988
12 Thread-1 inside 987
13 Thread-2 inside 987
14 Thread-3 inside 987
15 Thread-4 inside 987
My question is why the threads in the for loop are still reading the value of value
variable as 987
and not 988
, even after implementing volatile keyword.
Will deeply appreciate answer to this problem.
This has nothing to do with multithreading at all, it is a much more fundamental issue.
class ThreadEx4 extends Thread{
private int i;
public ThreadEx4(int i) {
this.i=i;
}
public void run() {
++i;
System.out.println("changed the value to "+i);
}
}
You are changing your private variable i
here, not the global static
field.
Java passes things around by value. So when you say new ThreadEx4(myInteger)
, the constructor will receive the number inside of myInteger
. Whatever it does to its local copy does not affect myInteger
at all.
To continue your multi-threading experiments, get rid of the local variables and do
class Ex4 extends Runnable {
@Override
public void run(){
int newValue = ++UnSyncRead.value;
System.out.println("changed the value to "+newValue);
}
}
// and the same for the other runnables