java并发编程学习之Volatile

8次阅读

共计 814 个字符,预计需要花费 3 分钟才能阅读完成。

多线程为什么是不安全的

这边简单的讲述一下,参考 java 并发编程学习之 synchronize(一)

  • 当线程 A 和线程 B 同时进入 num = num + value;
  • 线程 A 会把 num 的值拿出来,放在自己的工作区间里
  • 线程 B 也把 num 的值拿出来,放在自己的工作区间里
  • 线程 A 计算完,把值回填到 num
  • 这个时候,线程 B 的值还是原来的,计算完后,把值回填到 num,就直接覆盖了线程 A 的值

Volatile 知识

volatile 变量,是稍弱的同步机制,不会被缓存到寄存器或者其他处理器不可见的地方,因此读取时,总会返回当前的最新值。这个性质,就是可变性,是 Volatile 的关键作用之一。但是 Volatile 的语义不足以确保递增操作的原子性,在多线程的情况下,线程不一定是安全的。

常用场景:

  1. 单例模式(懒汉模式)


我们模拟两个线程 A,B,在还没创建单例对象的时候,一起进入 getInstance 方法。

  • A 进入 16 行,此时 singleton 为空,时间片结束。
  • B 也进入 16 行,获取到的 singleton 也是空,时间片结束。
  • A 进入 17 行,这边是类锁,,B 在等待 A 执行完这个代码块。
  • A 执行完,生成 singleton 对象。
  • B 继续执行,这边注意一下,因为是 Volatile 具有可见性的特性,此时,他是知道 singleton 不为空,已经被实例化了,于是就不继续实例化。如果 B 不是 Volatile 变量,那么,他就又实例化 singleton,就破坏了单例的结构。
  1. 检查某个状态标记,以判断是否退出循环
Volatile boolean done;
....
某个方法 {while(done){doSomeThing1();
    }
    doSomeThing2();}

这边和用普通的变量的区别是,在多线程的情况下,取到 done 后,done 的值被改变了,while 判断会不正确。

使用的条件

  1. 对变量的写入操作,不依赖变量的当前值,或者确保单线程更新变量的值
  2. 该变量不会和其他变量一起纳入不变形条件中
  3. 访问变量时,不需要加锁

正文完
 0