Home Inserting System.out.println calls affects race conditions: how to debug?
Reply: 0

Inserting System.out.println calls affects race conditions: how to debug?

user2555
1#
user2555 Published in June 19, 2018, 11:53 pm

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

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.414123 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO