- 可见性(visibility)
- 有序性(禁止指令重排)
- 不具备原子性
volatile是采用“内存屏障”来实现的。JVM会为volatile变量多加一个lock前缀指令
- 每个线程有自己的工作内存,同时还有一个共享的主内存。
- 每个线程会从主内存中Load 变量值,到本次工作内存。可以理解为是变量的副本
- 每次使用就可以直接从工作内存里加载了,不需要再从主内存里加载了。若每次都从主内存加载,性能会比较差
- 若被volatile 来修饰的变量,被其它线程修改,优先更新本地工作内存后强制将变更后值刷新回主内存。
- 通过cpu总线嗅探来监听,mesi缓存一致性协议使其他线程的本地副本失效。
- 当其它线程读取变量值的时候,本地的副本失效,将强制重新从主内存来加载最新的值。
volatile可以禁止指令重排,这就保证了代码的程序会严格按照代码的先后顺序执行。(否则,普通的变量可能由于指令重排在赋值 *** 作中被打乱顺序,导致赋值错误)
4.JMM的原子 *** 作方法 5.使用场景- 般用于 状态标记量 和 单例模式的双检锁
附录:其它
注意:volatile只能保证变量的可见性,不能保证对volatile变量 *** 作的原子性,见如下代码:
mesi缓存一致性协议
cpu总线嗅探,使当前cpu的变量失效,重新获取主内存的变量值
volatile关键字是C写的,从汇编语言,写会主内存的时候其实也会加锁
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)