I am learning java multithreading new. I was experimenting with some normal code. My target was to parallelly run two threads that will print the value of a static variable each time after incrementing. I was expecting the output will show the value of the static variable c increasing order from 1 to 10. But after running the program it is showing differently. My question is if the variable is shared between the two threads, shouldn't thread 1 display the value of c as 3 as it will get c from the same memory location after thread 2 has incremented it to 2? Also why the value of variable c is not reaching 10? Here is my code:
public class Test1 {
public static int c=0;
public static void main(String[] args){
Thread t1=new Thread(()-> {
for(int i=0;i<5;i ){
c ;
System.out.println("In thread 1: " c);
}
});
Thread t2=new Thread(()-> {
for(int i=0;i<5;i ){
c ;
System.out.println("In thread 2: " c);
}
});
t1.start();
t2.start();
}
}
Here is the output:
>>
In thread 2: 1
In thread 2: 2
In thread 1: 1
In thread 1: 4
In thread 2: 3
In thread 1: 5
In thread 2: 6
In thread 1: 7
In thread 2: 8
In thread 1: 9
CodePudding user response:
This is because c
is not atomic operation but rather shorthand for something like
int arg=c;
int result = arg 1;
c=result; //does not matter if it is 2 or 3 lines variant. What matters is that there are more that 1 operations here
(operation beeing atomic here means that it cannot be divided into smaller pieces - which is not the case as shown above)
As you can see, you have separation between reading c
and writing to it. Thread execution can switch in any time on any of those lines (read and write) which can result in for example, bot threads reading the same value of c
which will result in "skipped" result (increment in your case)
This pheonomenon is well know as "racing conditions" and code you have provided is actually a common snippet to demonstrate this.
You have either synchronize access to the c
so you strictly forbid threads to be switched in-between operation or use implementations that can do it "atomically" - usually using some cpu level magic CAS operations.
CodePudding user response:
you need to block the access to the variable while one thread is using it