Eniac Zhang wrote:
Hi all,
My colleague and I found this while debugging our program. We created
a simple program to duplicate the issue. So here's the program:
public class VolatileVar {
static class Worker implements Runnable {
public static Integer total = 0;
public static Object dummy = new Object();
public int count = 0;
public void run() {
while (!Thread.interrupted()) {
synchronized (total) {
total++;
You have been fooled by "auto-boxing," an evil addition
to Java that was intended to make it easier to use but in
actuality just makes it more confusing.
Keep in mind that operators like `++' work on primitive
variables, not on objects like Integer instances. The compiler
has actually translated `total++;' as if you had written
total = new Integer(total.intValue() + 1);
.... or perhaps it uses Integer.valueOf() instead of calling the
constructor; I'm not certain. Either way, `total' after this
assignment refers to a different Integer instance than the one
the code synchronizes on -- and the accesses to the `total'
reference itself are not synchronized at all. So when multiple
threads execute this code you have race conditions; the outcome
will be (in general) unpredictable.
Also, there is no synchronization on 'count' whatsoever.