java中的易失性关键字错误

时间:2015-03-30 07:37:34

标签: java multithreading volatile

我正在尝试编写一个简单的代码来理解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 ,但有时我会得到一个不同的数字。   请帮我理解这是怎么可能的

2 个答案:

答案 0 :(得分:4)

volatile关键字的作用大致是对该变量的每个单独的读或写操作都是原子的。

然而,值得注意的是,需要多个读/写的操作 - 例如i ++,相当于i = i + 1,它执行一次读取和一次写入 - 不是原子的,因为另一个线程可能在读和写之间写入i。

答案 1 :(得分:3)

Runner.count+=1;

表示:

Runner.count = Runner.count + 1;

或换句话说:

  1. 获取Runner.count
  2. 的值
  3. 为此值添加1。
  4. 将新值存储在Runner.count
  5. 线程A和B都可以获得Runner.count的值(所以它们都得到1),然后两者同时加1(所以它们都得到2),然后两者都存储它同时返回(所以新值为2) - 现在值从1变为2,而不是1到3,即使两个线程增加了它!