import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class Main implements Runnable {
private final CountDownLatch cdl1 = new CountDownLatch(NUM_THREADS);
private volatile int bar = 0;
private AtomicInteger count = new AtomicInteger(0);
private static final int NUM_THREADS = 25;
public static void main(String[] args) {
Main main = new Main();
for(int i = 0; i < NUM_THREADS; i++)
new Thread(main).start();
}
public void run() {
int i = count.incrementAndGet();
cdl1.countDown();
try {
cdl1.await();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
bar = i;
if(bar != i)
System.out.println("Bar not equal to i");
else
System.out.println("Bar equal to i");
}
}
Each Thread
enters the run method and acquires a unique, thread confined, int
variable i
by getting a value from the AtomicInteger
called count
. Each Thread
then awaits the CountDownLatch
called cdl1
(when the last Thread
reaches the latch, all Threads
are released). When the latch is released each thread attempts to assign their confined i
value to the shared, volatile
, int
called bar
.
I would expect every Thread
except one to print out "Bar not equal to i", but every Thread
prints "Bar equal to i". Eh, wtf does volatile
actually do if not this?
It is a deliberate intention that each Thread
attempts to set the value of bar
at exactly the same time.
EDIT:
In light of the answer, changed code to this:
...
bar = i;
try {
Thread.sleep(0);
} catch(InterruptedException e) {
e.printStackTrace();
}
...
To ensure that a little time is wasted between the set and read of the variable.
Now the print is 50/50 on same/different value for Bar.