在多线程并发编程当中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);
网友评论