我的代码如下:
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的输出。是什么导致这个?
答案 0 :(得分: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()
。
答案 1 :(得分:1)
因为来自一个线程的更新可能在另一个线程中不可见:
可见性: cpu缓存主内存中的值。因此,在没有缓存失效的情况下,第二个cpu上运行的线程将看不到第一个cpu上运行的线程所写的值。在java中的synchronized语句,包java.util.concurrent中的volatile字段和类。使cpu缓存无效。
(见http://blog.vmlens.com/2013/08/18/java-race-conditions-or-how-to-find-an-irreproducable-bug/)