如果一个javabean会被并发访问,比如读写其定义的属性字段,那么为了确保线程读取字段的值是最新的,是不是意味着这个类所有的字段都要用volatile关键字修饰?虽然我觉得应该如此,但是在本地写测试代码似乎没有测试出反例,即:不加volatile,也第一时间就读取到了最新值,这是怎么回事呢?是否和JVM的window版本、linux版本有关?又获取与硬件CPU有关?

解决方案 »

  1.   

    https://www.cnblogs.com/zhengbin/p/5654805.html
    看看这篇文章吧
      

  2.   

    volatile主要是用在并发读写的场景。这样让读可以得到最新写的数据。遵守happens-before规范
      

  3.   

    先说结论 为了确保线程读取字段的值是最新的 是要用volatile 其次你说volatile变量涉及读写 那你在操作volatile变量时还要加锁首先实现并发安全要保证三点:1、原子性  2、可见性  3、有序性   volatile可以保证可见性和一定程度的有序性不可以保证原子性 
    比如 volatile int i; i++这种操作就不是原子性的 需要注意处理 所以volatile修饰并不是就保证并发安全 还要具体看场景
    volatile变量可见性是通过写立即提交到内存和通知失效实现的 有序性是通过内存屏障禁止重排序实现的以下摘自深入理解java虚拟机
    在不符合一下两条规则的运算场景中,仍然要通过加锁来保证原子性
    1 运算结果并不依赖变量的当前值,或者能够确保只有单一线程修改变量的值。
    2 变量不需要与其他的状态变量共同参与不变约束。如有不对之处多多指教
      

  4.   

    volatile 个人认为是在多处写的时候用到,如果一写多读,加不加关键字无所谓的,你能在乎几万分之一秒?典型的应用就是double check的单例的使用,内层实例化后,外层立马能感知到,再进入第二层判断时能够得知已经实例化,直接获取,而不是再次实例化。 自己测试得用死循环,模拟大量并发,应该比较难。
      

  5.   

    声明变量是 volatile 的,JVM 保证了每次读变量都从内存中读,跳过 CPU cache 这一步