意圖:保證一個類只有一個實例,並提供一個訪問它的合局訪問點。多線程
示例一:使用內部靜態類的方式保存INSTANCE函數
1 /** 2 * Created by wiikii on 14-5-12. 3 */ 4 public class Singleton implements Serializable { 5 6 // 使用靜態內部類保存INSTANCE 7 private static class SingletonHolder { 8 private static final Singleton _INSTANCE = new Singleton(); 9 } 10 11 // 私有化構造函數 private or protected? 12 private Singleton() {} 13 14 // 對外接口,獲取惟一實例句柄 15 public static Singleton Instance() { 16 return SingletonHolder._INSTANCE; 17 } 18 19 // readResolve方法應對單例對象被序列化時候 20 private Object readResolve() { 21 return Instance(); 22 } 23 }
示例二:使用synchronized來保證線程同步。spa
1 /** 2 * Created by wiikii on 14-5-12. 3 */ 4 public class Singleton implements Serializable { 5 6 private volatile static Singleton _INSTANCE; 7 8 private Singleton() {} 9 10 public static Singleton Instance() { 11 if (_INSTANCE == null) { 12 synchronized (Singleton.class) { 13 if (_INSTANCE == null) { 14 _INSTANCE = new Singleton(); 15 } 16 } 17 } 18 return _INSTANCE; 19 } 20 }
注:線程
volatile 表示易失變量,主要用於多線程中。
爲了提升效率,線程會將某變量(A)拷貝一份(B)到內存,線程對變量的訪問實際訪問的是(B),只是在某些特定的操做後,纔會同步(A)與(B);所以有可能會存在(A)與(B)不一致的狀況。使用volatile修飾的變量,就是告訴JVM不須要變量(A)的拷貝。
若是volatile關鍵字用於聲明簡單數據類型(如 int, boolean 等),那麼對這些變量的操做將會是原子級別的;可是,若是當變量的值由自身的上一個值決定時,volatile將失效。