以上
如果你想了解更多请往下读
一、什么事内存可见性呢?
我们都知道处理器有多个核,每个核都有cache,这样每个核的cache就可能发生不同步的情况,一个核心对这个变量做了修改而另一个核心中因为cache的存在而不知道次变量已经修改。
volatile修饰的变量不允许线程(核)内部缓存和重排序,即直接修改内存。所以对其他线程是可见的。声明变量是 volatile 的,JVM 保证了每次读变量都从内存中读,跳过 CPU cache 这一步。
二、指令重排是啥?
是指CPU采用了允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理。
instance = new Instancce()
上面的代码虽然只有一行,但不是原子操作,它分成3步。
1.开辟内存空间 2.初始化对象 3.把初始化的对象指向内存地址上 复制代码
这3步的执行顺序是不一定的,可能是132或123这样。 如果是132这样,在13之后程序意外终止,instance!=null,但是instance还没初始化完成!
如果加了volatile关键字就禁止了指令重排。程序是1223这样执行,如果12或1执行了之后程序意外终止,instance还是null。