简体   繁体   中英

Why does my application return wrong output SOME of the time?

I have this code below:

public class Test1 {

private static long value = 0;

public static void main(String[] args) {
    Thread1 k = new Thread1();
    Thread1 t = new Thread1();
    k.start();
    t.start();
    while (k.isAlive() & t.isAlive());
    System.out.println(value);
}

public static void addOne() {
    long temp = value;
    temp = temp + 1;
    value = temp;
}
}

class Thread1 extends Thread {

public void run() {
    for (int i=0; i<100; i++)
        Test1.addOne();
}

}

And usually when I run it I get an output of 200, but very few times I get output like 100 and 151. What causes this?

Thread scheduling is unpredictable:

public static void addOne() {
    long temp = value;
    // Assume the thread is somewhere here when the system
    // puts it to sleep
    temp = temp + 1;
    // ...or here
    // ... Then the old value is used when it gets cpu time again
    value = temp;
}

To fix, for example:

public static synchronized void addOne() ...

prevents the threads from stepping on each other's toes. Another way would be using AtomicLong , and use incrementAndGet() .

Because the updates from one thread might not visible in the other thread:

Visibility: The cpu caches values from the main memory. Therefore a value written by thread running on the first cpu will not be seen by a thread running on the second cpu without cache invalidation. In java the synchronized statement, volatile fields and classes in the package java.util.concurrent. invalidate the cpu cache.

(see http://blog.vmlens.com/2013/08/18/java-race-conditions-or-how-to-find-an-irreproducable-bug/ )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM