初學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中只建立一個單例對象,保證了對象的原子性,可見性,防止重排序。