一. 懶漢式單例 //懶漢式單例類.在第一次調用的時候實例化自己 public class Singleton { private Singleton() {} private static Singleton single=null; //靜態工廠方法 public static Singleto ...
一. 懶漢式單例

//懶漢式單例類.在第一次調用的時候實例化自己 public class Singleton { private Singleton() {} private static Singleton single=null; //靜態工廠方法 public static Singleton getInstance() { if (single == null) { single = new Singleton(); } return single; } }View Code
以上懶漢式單例是線程不安全的,併發環境下很可能出現多個Singleton實例,要實現線程安全,有以下三種方式,
都是對getInstance這個方法改造,保證了懶漢式單例的線程安全。
1. 在getInstance方法上加同步

public static synchronized Singleton getInstance() { if (single == null) { single = new Singleton(); } return single; }View Code
雖然線程安全了,但是每次都要同步,會影響性能
2. 雙重檢查鎖定

public static Singleton getInstance() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; }View Code
也是線程安全的,同時避免了每次都同步的性能損耗
3. 靜態內部類

public class Singleton { private static class LazyHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton (){} public static final Singleton getInstance() { return LazyHolder.INSTANCE; } }View Code
線程安全的,同時沒有性能損耗,所以一般我傾向於使用這一種
二. 餓漢式單例

//餓漢式單例類.在類初始化時,已經自行實例化 public class Singleton1 { private Singleton1() {} private static final Singleton1 single = new Singleton1(); //靜態工廠方法 public static Singleton1 getInstance() { return single; } }View Code
餓漢式在類創建的同時就已經創建好一個靜態的對象供系統使用,以後不再改變,所以天生是線程安全的。