So, follwoing some job interviews I wanted to write a small program to check that i++
really is non-atomic in java, and that one should, in practice,add some locking to protect it. Turns out you should, but this is not the question here.
So I wrote this program here just to check it.
The thing is, it hangs. It seems that the main thread is stuck on on t1.join()
line, even though both worker threads should finish because of the stop = true
from previous line.
I found that the hanging stops if :
- I add some printing inside the worker threads (as in the comments), probably causing the worker threads to sometime give up CPU or
- If I mark the flag
boolean stop
asvolatile
, causing the write to immediately be seen by worker threads, or - If I mark the counter
t
asvolatile
... for this I have no idea what causes the un-hanging.
Can someone explain what's going on? why do I see the hang and why does it stop in those three cases?
public class Test {
static /* volatile */ long t = 0;
static long[] counters = new long[2];
static /* volatile */ boolean stop = false;
static Object o = new Object();
public static void main(String[] args)
{
Thread t1 = createThread(0);
Thread t2 = createThread(1);
t1.start();
t2.start();
Thread.sleep(1000);
stop = true;
t1.join();
t2.join();
System.out.println("counter : " + t + " counters : " + counters[0] + ", " + counters[1] + " (sum : " + (counters[0] + counters[1]) + ")");
}
private static Thread createThread(final int i)
{
Thread thread = new Thread() {
public void run() {
while (!stop)
{
// synchronized (o) {
t++;
// }
// if (counters[i] % 1000000 == 0)
// {
// System.out.println(i + ")" + counters[i]);
// }
counters[i]++;
}
};
};
return thread;
}
}