In: Computer Science
Create a project named Bonus that first demonstrates a race condition using this scenario, then make it thread-safe and show what the execution would look like after your fix.
I need my code to be in java with fully commented
The first class Bonus demonstrates the race condition.
//In this example of race condition in Java multi-threading, we have a shared instance variable. Since there are three threads sharing
//the same object of the class so the field in the object is shared among the threads. This instance variable c is incremented and decremented so
//every thread should leave it in the state it initially was i.e. if c is zero in the start, incrementing it will make it 1 and decrementing it will
//make it zero again.
public class Bonus implements Runnable{
private int x = 0;
public void increment() {
try {
Thread.sleep(10); //sleep(n) induces delay in a specific thread by n ms or ns.
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace(); //printStackTrace() prints the throwable along with the line number and class name where the exception occurred.
}
x++;
}
public void decrement() {
x--;
}
public int getValue() {
return x;
}
@Override
public void run() { //when run() method is called the code inside run() gets executed. calling start() method executes run() method.
//incrementing
this.increment();
System.out.println("The value for Thread After incrementing: "
+ Thread.currentThread().getName() + " " + this.getValue());
//decrementing
this.decrement();
System.out.println("The value for Thread at the end: "
+ Thread.currentThread().getName() + " " + this.getValue());
}
}
class RaceConditionDemo{
public static void main(String[] args) {
Bonus bonus = new Bonus();
Thread t1 = new Thread(bonus, "Thread-1");
Thread t2 = new Thread(bonus, "Thread-2");
Thread t3 = new Thread(bonus, "Thread-3");
t1.start(); //start() method is used to start the implementation of thread and it also calls the run() method.
t2.start();
t3.start();
}
}
The output of the above code shows how the shared variable c gives the wrong values.
Below is a Thread-safe which avoids race-condition in java.
//To fix the race condition we need to have a way to restrict resource access to only one thread at a time. We have to use synchronized keyword to
//synchronize the access to the shared resource.
public class Bonus implements Runnable{
private int x = 0;
public void increment() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
x++;
}
public void decrement() {
x--;
}
public int getValue() {
return x;
}
@Override
public void run() {
//All synchronized blocks synchronized on the same object can only have one thread executing inside them at the same time.
//All other threads attempting to enter the synchronized block are blocked until the thread inside the synchronized block exits the block.
synchronized(this){
// incrementing
this.increment();
System.out.println("The value for Thread after incrementing: "
+ Thread.currentThread().getName() + " " + this.getValue());
//decrementing
this.decrement();
System.out.println("The value for Thread at the end: " + Thread.currentThread().getName()
+ " " + this.getValue());
}
}
}
class RaceConditionDemo{
public static void main(String[] args) {
Bonus counter = new Bonus();
Thread t1 = new Thread(counter, "Thread-1");
Thread t2 = new Thread(counter, "Thread-2");
Thread t3 = new Thread(counter, "Thread-3");
t1.start();
t2.start();
t3.start();
}
}