面试篇 —— 谈谈你对volatile关键字的理解

volatile关键字的理解

一、volatile是什么

volatile是JVM虚拟机提供的轻量级同步机制

  1. 保证可见性:当数据存储到主内存中时,其他线程要使用数据,会将其拷贝一份到自己的工作内存中进行操作,改变数据后再赋值给主内存,为了保证与其他线程数据同步,需要通知其他已拿到拷贝数据的线程。volatile修饰的数据,会将线程名称作为key进行存储。
  2. 不保证原子性:多线程环境中可能出现数据写入丢失的情况。可以使用Atomic原子包装类保证数据的原子性。
  3. 禁止指令重排:指令重排是编译器或处理器在执行文件时进行指令重排优化,多线程情况下可能出现乱序执行,导致数据失去准确性。

二、JMM内存规则

  1. 保证可见性:使用关键字volatile
  2. 原子性:动作执行的完整性。
  3. 有序性

三、DCL单例模式使用volatile

  1. 单例源码:
public class SingletonDemo {
	private static volatile SingletonDemo instances = null;
	private SingletonDemo() {}
	publuc static SingletonDemo getInstances() {
		if (instances == null) {
			synchronized(SingletonDemo.class) {
				if (instances == null) {
					instances = new SingletonDemo();
				}
			}
		}
		return instances;
	}
}
  1. 使用volatile解析:多线程情况下,编译器或处理器可能出现指令重排优化。new对象的执行步骤如下
  • 分配内存空间
  • 进行对象初始化操作,也就是执行init()
  • 赋值内存地址,此时instances != null
    如果在进行new对象的时候发生指令重排,变成了先赋值内存地址,再执行初始化,那么就可能有线程获取到只有内存地址没有初始化实例的对象,发生异常。而volatile能够禁止编译器或处理器进行指令重排,符合JMM原则,保证了操作执行的有序性。

面试篇 —— 谈谈你对volatile关键字的理解

上一篇:module.exports与exports和export和export default区别


下一篇:VS2015 打开时默认使用管理员权限