volatile关键字剖析
这里引入一个案例 :实现单例模式的双重检查锁
package com.chunling.cloud.test; |
讨论:此案例中的instance实例是否应该被volatile关键字修饰呢? 官方给的答案是要加volatile关键字;
讲到这里,先来阐述下啊volatile的作用:
1.保证各线程对其修饰变量的可见性(通过总线锁/cpu三级缓存锁实现)
就可见性问题而言:即使不加volatile ,我们的instance实例也能被线程共享(静态成员变量是存储在jvm运行时数据区的方法区【方法区的内容会被线程共享】);
所以上面代码中加同步上锁后,保证了线程访问的顺序性,所以也保证了对象一定是单例的;
2.防止指令重排序(这里不是我们java代码的指令)
如上面示例中的value属性,jvm在初始化instance对象时会经历三步(类似于我们spring的三级缓存的过程),
step1:实例化对象instance,此时value的值为0;
step2:给instance对象赋值,value=8;
step1:给instance和value建立连接,即将value设置为instance的成员变量;
所以这个过程有可能会造成step1实例化完之后对象返回了,后续线程可能会拿到一个没有初始化的instance对象。
但是:经过验证 如果不加volatile关键字的话 实例化出来的对象一样 且对象内部的value值也一样;
可能是因为我对对象的加载过程还没有深度研究的原因吧,待研究完后再来打脸。。。。