I was running an experiment on different approaches to deal with race condition in multi-threaded java applications . Strategies like atomic variables, synchronize worked well , but I dont see the issue being solved when using volatile variables. Here the code and output for reference.
Can you please guide on what could be the reason for the volatile variable to still lead to a race condition?
package com.shyam.concurrency;
public class main {
public static void main(String[] args) {
demoClass dm1 = new demoClass();
Thread th1 = new Thread(()->{
int i =0;
do {
i++;
dm1.setCounter();
dm1.setAtomicCounter();
dm1.setSyncCounter();
dm1.setVolatileCounter();
} while (i < 100000);
});
Thread th2 = new Thread(()->{
int i =0;
do {
i++;
dm1.setCounter();
dm1.setAtomicCounter();
dm1.setSyncCounter();
dm1.setVolatileCounter();
} while (i < 100000);
});
th1.start();
th2.start();
try {
th1.join();
th2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Normal counter(Race condition) : " + dm1.getCounter() );
System.out.println("Synchronized counter is :" + dm1.getSyncCounter());
System.out.println("Atomic counter is :" + dm1.getAtomicCounter());
System.out.println("Volatile counter is :" + dm1.getVolatileCounter());
The code that has the increment logic is here:
package com.shyam.concurrency;
import java.util.concurrent.atomic.AtomicInteger;
public class demoClass {
private int counter ;
private int syncCounter;
private volatile int volatileCounter = 0;
private AtomicInteger atomicCounter = new AtomicInteger() ;
public int getAtomicCounter() {
return atomicCounter.intValue();
}
public void setAtomicCounter() {
this.atomicCounter.addAndGet(1);
}
public int getCounter() {
return counter;
}
public void setCounter() {
this.counter++;
}
public synchronized int getSyncCounter() {
return syncCounter;
}
public synchronized void setSyncCounter() {
this.syncCounter++;
}
public int getVolatileCounter() {
return volatileCounter;
}
public void setVolatileCounter() {
this.volatileCounter++;
}
}
And here's the output i get:
Normal counter(Race condition) : 197971
Synchronized counter is :200000
Atomic counter is :200000
Volatile counter is :199601