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.