我正在尝试编写一个简单的代码来理解java中的 volatile 关键字。
我们的想法是使用两个线程增加Runner类的 count 字段的值。 Helper类实现Runnable,其中run方法增加 static 和 volatile 的 count 。
class Helper implements Runnable{
@Override
public void run() {
for(int i=0; i<100000;i++){
Runner.count+=1;
}
}
}
public class Runner {
public static volatile long count=0; // to be incremented
public static void main(String[] args){
Thread t1 = new Thread( new Helper());
Thread t2 = new Thread( new Helper());
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Count= "+count); // output expected to be 200000
}
}
每次运行的预期输出是 Count = 200000 ,但有时我会得到一个不同的数字。 请帮我理解这是怎么可能的
答案 0 :(得分:4)
volatile关键字的作用大致是对该变量的每个单独的读或写操作都是原子的。
然而,值得注意的是,需要多个读/写的操作 - 例如i ++,相当于i = i + 1,它执行一次读取和一次写入 - 不是原子的,因为另一个线程可能在读和写之间写入i。
答案 1 :(得分:3)
Runner.count+=1;
表示:
Runner.count = Runner.count + 1;
或换句话说:
Runner.count
。Runner.count
。线程A和B都可以获得Runner.count
的值(所以它们都得到1),然后两者同时加1(所以它们都得到2),然后两者都存储它同时返回(所以新值为2) - 现在值从1变为2,而不是1到3,即使两个线程增加了它!