【问题标题】:Volatile keyword error in java [duplicate]java中的volatile关键字错误[重复]
【发布时间】:2015-06-03 03:26:28
【问题描述】:

我正在尝试编写一个简单的代码来理解 java 中的 volatile 关键字。

这个想法是使用两个线程来增加 Runner 类的 count 字段的值。 Helper 类实现了 Runnable,其中 run 方法增加 staticvolatilecount

        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 ,但有时我会得到不同的数字。 请帮助我了解这怎么可能

【问题讨论】:

  • Volatile 提供可见性,但不提供原子性(这是诸如变量增量之类的复合操作所需要的)。

标签: java multithreading volatile


【解决方案1】:

volatile 关键字的效果大约是对该变量的每个单独的读取或写入操作都是原子的。

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

【讨论】:

    【解决方案2】:
    Runner.count+=1;
    

    意思是:

    Runner.count = Runner.count + 1;
    

    或者,换句话说:

    1. 获取Runner.count的值。
    2. 将此值加 1。
    3. 将新值存储在Runner.count

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

    【讨论】:

      猜你喜欢
      • 2011-04-05
      • 2016-02-12
      • 2012-04-01
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-14
      相关资源
      最近更新 更多