I do not understand why the race condition in the following code disappears when adding println comments. This really makes debugging hard.
How can we debug these conditions then?
In the following code the machine should throw an Exception because the two threads modify the contents of the class in an inconsistent manner.
In fact checking the code b should always be greater or equal to a (class contract). However due to the race condition between the two threads this contract is not satisfied.
Without the comments the race condition happen and the code throws an exception but with the System.out.println comments I did not get any race condition.
Java version 1.8.0_112
package lectures;
import java.util.Random;
public class Concurrency1 {
int a,b;
void setEqual(int x){
// System.out.println("setEqual "+x);
a=x;
b=x;
}
void setRel(){
// System.out.println("setRel");
a++;
b+=a;
}
void checkContract() throws Exception{
if (b<a) throw new Exception("b<a!!, a="+a+" b="+b);
}
public static void main(String[] args) throws Exception{
Concurrency1 c1=new Concurrency1();
final int count=10000000;
Thread t1=new Thread(){
public void run(){
Random gen=new Random();
int c=0;
while(c++<count){
System.out.println("setEqual ");
c1.setEqual(gen.nextInt(10));
}
}};
Thread t2=new Thread(){
public void run(){
int c=0;
while(c++<count){
System.out.println("setGen ");
c1.setRel();
}
}};
t1.start();
t2.start();
int c=0;
while(t1.isAlive()||t2.isAlive()||c++<count){
c1.checkContract();
}
}
}
Without the println message I get exception messages like:
Exception in thread "main" java.lang.Exception: b<a!!, a=104 b=27966
at lectures.Concurrency1.checkContract(Concurrency1.java:20)
at lectures.Concurrency1.main(Concurrency1.java:48)
Where the values are changed after the check is done... This is different from Loop doesn't see changed value without a print statement as the threads are seeing each other changes and thus generate the exception