登录

java关键字volatile的作用

volatile 关键字都知道是不能做到线程同步的,只能保证线程之间尽快的获取最新的值,像 concurrentHashmap 之间 value 的修饰就用到了 volatile,我感觉这个关键在没啥用的感觉,,,求解释。

或者说 volatile变量修饰符适用于什么场景?

# Java
ringa_leeringa_lee2147 天前557 次浏览

全部回复(5) 我要回复

  • 迷茫

    迷茫2017-04-17 11:30:57

    关于java volatile, 我有几点说明,

    • volatile保证 可见性. 即线程得到的 值是 最新的. Thread1 改变了 var的值, 那么Thread2再去读, 就是改变了的值, 而不是以前的. 再具体一点, 我的理解是这样(有误请指出), 现代计算机都是多核或多cpu, 一个变量可能在同一时间, 存在与不同的cpu的 寄存器里. 如果没有volatile做保证, 那么同一时间 统一变量会有不同的值. volatile保证每次都是从 主存中读取/写入 变量的值, 从而保证可见性.

    • volatile保证 编译器不会过度优化. 见过以下的例子, 大概的代码是这样:

        public class Thread1 extends Thread {
          private boolean flag = false;
          public void run() {
            while(!flag) {
              // ...
            }
          }
          public void close() {
            flag = true;
          }
        }
    

    但是在外部进程调用close()后, Thread1并没有退出. 用了jdk debug版本 拿到了hotspot 的汇编码. 发现这里while(!flag) 被编译器优化为 while(true).

    • 对long或double来说, 读写不是 原子操作. 加了volatile, 对long或double的读写为 原子操作.

    回复
    0
  • 怪我咯

    怪我咯2017-04-17 11:30:57

    用于修饰 多线程共享变量。使用此关键字保证jvm不会从线程变量中读写,而是直接操作共享变量

    回复
    0
  • 迷茫

    迷茫2017-04-17 11:30:57

    我的理解是:如果有一个变量,有多个线程读,但只有一个线程写,那么此变量用 volatile 可以保证读到正确的值。volatile 的一个经典的应用是 Double-checked locking ,它是一种在多线程环境下正确且高效地实现单例模式的方法。

    参考:

    • java 多线程读一个变量需要加锁吗

    回复
    0
  • 高洛峰

    高洛峰2017-04-17 11:30:57

    volatile是保证被修饰变量的可见性,而不保证原子操作,经典应用是Double-checked locking。比如在多线程环境下修饰一个boolean变量。

    回复
    0
  • PHP中文网

    PHP中文网2017-04-17 11:30:57

    楼主可以看下 infoq 的这篇文章:volatile

    回复
    0
  • 取消回复发送