The following snippet of code uses multiple threads to count to 100 million using an AtomicInteger. I have 10 Writer threads to simulate write contention and a single Reader thread to simulate read contention. The Writer and Reader also share a volatile boolean variable as a poison pill.
However, only the Reader thread is able to exit while the Writers are not. Despite declaring the variable as volatile, why aren't the Reader threads able to see the updated value?
public class AtomicRunnerV2 {
private static final int THREADS = 10;
private static final Integer MAX_COUNT = 100_000_000;
public static void main(String[] args) throws Exception {
AtomicInteger atomicInteger = new AtomicInteger(1);
Boolean data = new Boolean(false);
ExecutorService executorService = Executors.newFixedThreadPool(THREADS + 1);
for (int i = 0; i < THREADS; i++) {
executorService.submit(new Writer(atomicInteger, data));
}
executorService.submit(new Reader(atomicInteger, data));
executorService.shutdown();
}
static class Writer implements Runnable {
private AtomicInteger integer;
private volatile Boolean data;
Writer(final AtomicInteger integer, Boolean data) {
this.integer = integer;
this.data = data;
}
@Override public void run() {
while (!data) {
integer.incrementAndGet();
}
System.out.println("count " + integer.get() + " from WRITER!");
}
}
static class Reader implements Runnable {
private AtomicInteger integer;
private volatile Boolean data;
Reader(final AtomicInteger integer, Boolean data) {
this.integer = integer;
this.data = data;
}
@Override public void run() {
while (!data) {
if (integer.get() >= MAX_COUNT) {
data = true;
}
}
System.out.println("count " + integer.get() + " from READER!");
}
}
}
P.S: If I wrap the boolean in an object, it works.