Rajesh Rajesh - 4 months ago 9
Java Question

How to reproduce race condition in java?

I tried to create a race condition like this.

class Bankaccount {

private int balance=101;

public int getBalance(){
return balance;
}
public void withdraw(int i){
balance=balance-i;
System.out.println("..."+balance);
}
}


public class Job implements Runnable{

Bankaccount b=new Bankaccount();

public void run(){
if(b.getBalance()>100){
System.out.println("the balanced ammount is"+b.getBalance());
/*try{
Thread.sleep(9000);
}
catch(Exception e){

}*/
makeWithdrawl(100);
}
}

public void makeWithdrawl(int ammount){

b.withdraw(ammount);
System.out.println(b.getBalance());

}
public static void main(String[] args) {

Job x=new Job();
Job y=new Job();

Thread t1=new Thread(x);
Thread t2=new Thread(y);
t1.start();
t2.start();
}

}


I am getting output:
the balanced ammount is101
...1
1
the balanced ammount is101
...1

I was expecting it to be in negative as two times withdrawal happened for 100

What is missing here? Thanks in Advance

Answer

Race conditions appear when multiple threads change shared data. In your example each thread has its own Bankaccount class. You need to make it shared, like this:

class Job implements Runnable{

    Bankaccount b;

    Job(Bankaccount b){
        this.b = b;
    }

    public void run(){
        if (b != null)
            if(b.getBalance()>100){
                System.out.println("the balanced ammount is " + b.getBalance());
                makeWithdrawal(100);
            }
    }

    public void makeWithdrawal(int ammount){
        b.withdraw(ammount);
        System.out.println(b.getBalance());
    }

    public static void main(String[] args) {

        // Creating one Bankaccount instance
        Bankaccount b = new Bankaccount();

        // Passing one instance to different threads 
        Job x=new Job(b);
        Job y=new Job(b);

        Thread t1=new Thread(x);
        Thread t2=new Thread(y);

        // Race conditions may appear 
        t1.start();
        t2.start();
    }

}

Unfortunately, this is not enough. Multithreaded programs are non deterministic and you can receive different results after several executions of the program. For example, thread t1 can manage to make withdrawal before thread t2 start to check the balance. Hence, t2 will not do withdrawal due to lack of many.

To increase the likelihood of the negative balance you can insert delay between checking the balance and withdrawing money.