volatile修饰符

在多线程并发编程当中synchronized和volatile都扮演着重要的角色,volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”。可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。如果volatile变量修饰符使用恰当的话,它比synchronized的使用和执行成本更低,因为它不会引起线程上下文的切换和调度。


CPU的术语定义

volatile保证可见性

Java代码如下
instance = new Singleton(); // instance是volatile变量

转变成汇编代码,如下。

0x01a3de1d: movb 0×0,(%esp);

有volatile变量修饰的共享变量进行写操作的时候会多出第二行汇编代码,Lock前缀的指令在多核处理器下引发了两件事情.

  • 1)将当前处理器缓存行(Cache Line)写回系统内存(也就是主内存).
  • 2)这个写回内存操作将会使得其他CPU里缓存了该内存地址的数据无效

volatile的两条实现原则

  • 1)Lock前缀指令会引起处理器缓存回写到内存。
  • 2)一个处理器的缓存回写到内存会导致其他处理器的缓存无效。

volatile的实现机制

通过内存屏障和禁止重排序优化来实现

  • 对volatile变量写操作时,会在写操作后加入一条store屏障指令,将本地内存中的共享变量刷新到主内存


  • 对volatile变量读操作时,会在读操作钱加入一条load屏障命令,从主内存中读取共享变量



volatile的应用场景

volatile不具有原子性,所以不适合用于计数等场景
volatile的使用具有条件

  • 1.对变量的写操作不依赖当前值
  • 2.该变量不包含于其他变量的不变式当中

适合作为标记量,双重检测
eg:

volatile boolean inited = false;
//thread 1
context = loadContext();
inited = false;

//thread 2
while(!inited){
    sleep();
}
doSomethingWithConfig(context);

你可能感兴趣的:(volatile修饰符)