1

我在下面有这段代码:

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();
}

}

通常当我运行它时,我会得到 200 的输出,但很少会得到像 100 和 151 这样的输出。这是什么原因造成的?

4

2 回答 2

5

线程调度是不可预测的:

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;
}

修复,例如:

public static synchronized void addOne() ...

防止线程踩到彼此的脚趾。另一种方法是使用AtomicLong,然后使用incrementAndGet().

于 2013-09-14T15:57:32.447 回答
1

因为来自一个线程的更新可能在另一个线程中不可见:

可见性: cpu 缓存来自主内存的值。因此,在没有缓存失效的情况下,运行在第一个 cpu 上的线程将不会看到运行在第二个 cpu 上的线程所写入的值。java中的synchronized语句、volatile字段和类都在包java.util.concurrent中。使 cpu 缓存无效。

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

于 2013-09-24T13:00:12.653 回答