Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to demonstrate race conditions around values that aren't published properly?

I am reading "Java Concurrency in practice" and looking at the example code on page 51.

According to the book this piece of code is at risk of of failure if it has not been published properly. Because I like to code examples and break them to prove how they work. I have tried to make it throw an AssertionError but have failed. (Leading me to my previous question)

Can anyone post sample code so that an AssertionError is thrown? Rule: Do not modify the Holder class.

public class Holder{
    private int n;

    public Holder(int n){
        this.n = n;
    }

    public void assertSanity(){
        if (n != n) {
            throw new AssertionError("This statement is false");
        }
    }
}

I have modified the class to make it more fragile but I still can not get an AssertionError thrown.

class Holder2 {
    private int n;
    private int n2;

    public Holder2(int n) throws InterruptedException{
        this.n = n;
        Thread.sleep(200);
        this.n2 = n;
    }

    public void assertSanity(){
        if (n != n2) {
            throw new AssertionError("This statement is false");
        }
    }
}

Is it possible to make either of the above classes throw an AssertionError? Or do we have to accept that they may occasionally do so and we can't write code to prove it?

like image 902
andy boot Avatar asked Apr 12 '10 19:04

andy boot


People also ask

How do you prove race condition?

Race conditions are inherently a result of non-determinism. If you cannot ensure that the calling sequence is secure, then introduce a number of run-time checks that verify the protocol invariants are honoured. Then, at least you will have evidence of a fault whenever they occur.

What are examples of race conditions?

A simple example of a race condition is a light switch. In some homes, there are multiple light switches connected to a common ceiling light. When these types of circuits are used, the switch position becomes irrelevant. If the light is on, moving either switch from its current position turns the light off.

What is a race condition where does it occur and how can it be avoided?

By definition, a race condition is a condition of a program where its behavior depends on relative timing or interleaving of multiple threads or processes. One or more possible outcomes may be undesirable, resulting in a bug. We refer to this kind of behavior as nondeterministic.

What are race conditions How race conditions occur in operating systems?

A race condition occurs when two threads access a shared variable at the same time. The first thread reads the variable, and the second thread reads the same value from the variable.


2 Answers

I'd run this on a multiprocessor machine for a few hours and see what happens(remove the sleep if you use your Holder2). Such race conditions might be rare, or not existant on your particular machine - but atleast try to provoke these one on a million cases , by trying millions of times.

class Checker {
  private Holder h;
  public Checker() {
   h = new Holder(42);
  }

  public void check() {
    h.assertSanity();
  }

  public void create(int n) {
   h = new Holder(n);
   }

}

public class MyThread extends thread{
  private bool check;
  private final Checker c;
  public MyThread(bool check,Checker c) {
    this.check = check;
    this.c = c;
  }
    public static void main(String[] args) {
      Checker c = new Checker();
      MyThread t1 = new MyThread(false,c);  
      MyThread t2 = new MyThread(true,c);
      t1.start();
      t2.start();
      t1.join();
      t2.join();
   }
   public void run() {
     int n = 0;
     while(true) {
       if(check) 
         c.check();
       else
         c.create(n++);
    }
   }
 }
}
like image 104
leeeroy Avatar answered Sep 18 '22 13:09

leeeroy


As BobbyShaftoe said in the other thread, you can't rely on just running the code enough times to show that the error can or cannot happen. If you think about this from an Assembly level, it will be very hard for n != n as it is so few calls and relies on the process being switched out at a really precise time.

If you want to be able to show whether a concurrent system is provably valid it would be better to model it using something like Labelled Transition Systems. Try the LTSA tool if you're interested in proving concurrency or finding errors.

http://www.doc.ic.ac.uk/ltsa/

like image 42
Oli Avatar answered Sep 17 '22 13:09

Oli