單例定義: 一個類只有一個實例,並提供一個全局訪問點。 巧妙利用了編程語言的一些語法規則:構造函數private, 然後提供一個public的方法返回類的一個實例;又方法和返回的類的實例都是static類型,所以只能被類所擁有,而不能被實例化類的對象擁有。這樣一個類就只能有一個實例了。 2. 加”s ...
單例定義:
一個類只有一個實例,並提供一個全局訪問點。
巧妙利用了編程語言的一些語法規則:構造函數private, 然後提供一個public的方法返回類的一個實例;又方法和返回的類的實例都是static類型,所以只能被類所擁有,而不能被實例化類的對象擁有。這樣一個類就只能有一個實例了。
- 最簡單的寫法(非線程安全,有叫它“懶漢式”的)
public class Singleton { private static Singleton uniqueInstance; private Singleton() {} public static Singleton getInstatnce() { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; } }
2. 加”synchronized“保證多線程下的線程安全(同步代碼塊,高頻訪問時,性能較差)
public class Singleton { private static Singleton uniqueInstance; private Singleton() {} public static synchronized Singleton getInstatnce() { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; } }
3. ”急切“或”餓漢“式(線程安全,因為JVM載入此類時立即創建此類的唯一實例)
public class Singleton { private static Singleton uniqueInstance = new Singleton(); private Singleton() {} public static Singleton getInstatnce() { return uniqueInstance; } }View Code
4. ”雙重檢查加鎖“ (面試常問)
public class Singleton { private volatile static Singleton uniqueInstance; private Singleton() {} public static Singleton getInstatnce() { if (uniqueInstance == null){ synchronized (Singleton.class) { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } } } return uniqueInstance; } }View Code
註:第一次檢查,如果實例不存在,則進入同步塊;進入同步塊後再次檢查,防止第二個線程在第一個線程執行第二次檢查之前,已經創建了一個實例。volatile 關鍵字將禁止指令重排序。