浅谈volatile
初学Java,最近总是碰到volatile关键字,下面说说自己的见解
volatile关键字主要有一下特性:
1.保证原子性;2.实现可见性;3.防止重排序;
1.在声明变量时,使用volatile关键字可以保证这个变量的原子性,保证了每次读/写时只会读到确定的数据。
例如普通的double和float类型都不保证原子性的,在读取这两种数据类型时,会先读取前32位,若此时此数据发生改变,
则数据是不安全的,可以使用volatile关键字;
2.可见性主要体现在多线程方面,当一个线程修改了某变量的值时,另一个线程没有看到,其原因是每个线程都有一个高速缓冲区,使用volatile则可保证每个线程读到同样的数据;
3.在声明一个变量时,JVM实例化一个对象可分为3步:
(1)分配内存空间;
(2)初始化对象;
(3)将内存空间的地址赋值给对应的引用;
而其中,第2,3步是可以改变顺序的,这样,在多线程环境下,这个弊端就暴露出来了,在重排序时可能会读到null值,接下来我们来看一个单例:
public class Singleton {
private volatile static boolean flag;
/* 私有构造方法,防止被实例化 */
private Singleton() {
if(!flag){
flag = false;
}else{
throw new RuntimeException("不能多次创建单例对象");
}
}
/* 此处使用一个内部类来维护单例 */
private static class SingletonFactory {
private static Singleton instance = new Singleton();
}
/* 获取实例 */
public static Singleton getInstance() {
return SingletonFactory.instance;
}
/* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */
private Object readResolve() {
return getInstance();
}
}
这里使用volatile关键字就是为了在JVM中只创建一个单例对象,保证了对象的原子性,可见性,防止重排序。