初学Java,最近老是碰到volatile关键字,下面说说本身的看法安全
volatile关键字主要有一下特性:多线程
1.保证原子性;2.实现可见性;3.防止重排序;线程
1.在声明变量时,使用volatile关键字能够保证这个变量的原子性,保证了每次读/写时只会读到肯定的数据。对象
例如普通的double和float类型都不保证原子性的,在读取这两种数据类型时,会先读取前32位,若此时此数据发生改变,排序
则数据是不安全的,能够使用volatile关键字;内存
2.可见性主要体如今多线程方面,当一个线程修改了某变量的值时,另外一个线程没有看到,其缘由是每一个线程都有一个高速缓冲区,使用volatile则可保证每一个线程读到一样的数据;get
3.在声明一个变量时,JVM实例化一个对象可分为3步:io
(1)分配内存空间;class
(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中只建立一个单例对象,保证了对象的原子性,可见性,防止重排序。