【Java設計模式】單例模式
阿新 • • 發佈:2019-02-15
package com.bufoon.test.gof.singleton; /** * 顧名思義,比較懈怠,就是需要的時候才會去建立例項, * 這是經典的延遲載入思想,還有快取的實現思路; * 它會有執行緒安全問題,可以加鎖,但是會影響效率, * 典型的時間換空間的策略; * @ClassName: LazySingleton * @Description: 懶漢式單例 * @author anling.song * @date 2017年7月6日 下午4:20:09 */ public class LazySingleton { private static LazySingleton instance = null; //私有化構造方法 private LazySingleton(){} /** * 執行緒安全問題 * @return */ public static LazySingleton getInstance1(){ if (instance == null) { instance = new LazySingleton(); } return instance; } /** * 加鎖能避免執行緒安全問題,但是效率有問題 * 因為每次呼叫都得先獲取鎖 * @return */ public synchronized static LazySingleton getInstance2(){ if (instance == null) { instance = new LazySingleton(); } return instance; } /** * 加鎖的另外一種實現方式,只會在第一次生成例項的時候去獲取鎖 * 提高效率,雙重判斷加鎖,如果通過反射還是會破壞單例模式 * @return */ public static LazySingleton getInstance3(){ if (instance == null) { synchronized (LazySingleton.class) { if (instance == null) { instance = new LazySingleton(); } } } return instance; } }
package com.bufoon.test.gof.singleton; /** * 餓漢式就是比較著急,所以會在類載入的時候就建立例項, * 由於它是在類載入的時候就建立了,所以沒有執行緒安全的問題, * 但是浪費資源,空間換時間; * @ClassName: HungrySingleton * @Description: 餓漢式單例 * @author anling.song * @date 2017年7月6日 下午4:17:37 */ public class HungrySingleton { private static HungrySingleton instance = new HungrySingleton(); //私有化構造方法 private HungrySingleton(){} public static HungrySingleton getInstance(){ return instance; } }
package com.bufoon.test.gof.singleton; /** * 結合懶漢餓漢兩種實現都會有點小小的缺陷, * 能不能解決既能延遲載入,又不會有安全問題呢? * 因為static是由jvm去控制線同步的,所以能解決執行緒安全問題; * 在單例類內新增一個靜態內部類,靜態內部類初始化類例項; * @ClassName: InnerStaticClassSingleton * @Description: 靜態內部類單例 * @author anling.song * @date 2017年7月6日 下午4:29:14 */ public class InnerStaticClassSingleton { private InnerStaticClassSingleton(){} /** * 在真正呼叫的時候才會初始化,實現了延遲載入 * 執行緒安全由jvm底層控制,所以是執行緒安全的 * @ClassName: InnerSingletonHolder * @Description: 靜態內部類 * @author anling.song * @date 2017年7月6日 下午4:30:36 */ private static class InnerSingletonHolder{ private static InnerStaticClassSingleton instance = new InnerStaticClassSingleton(); } public static InnerStaticClassSingleton getInstance(){ return InnerSingletonHolder.instance; } }
package com.bufoon.test.gof.singleton;
import java.util.HashMap;
import java.util.Map;
/**
* 在高效Java第二版上提到的一種實現方式,
* 因為列舉的一個屬性就是代表列舉類自己,
* 所以用來實現單例模式非常簡便和通俗易懂;
* @ClassName: EnumSingleton
* @Description: 列舉單例類
* @author anling.song
* @date 2017年7月6日 下午4:33:10
*/
public enum EnumSingleton {
enumInstance;
// 存花式剎停動作分數儲存
private Map<String, Integer> map = null;
/**
* Enum構造方法,JVM會保證呼叫時只初始化一次
*/
private EnumSingleton(){
System.out.println("初始化資料............");
if (map == null) {
map = new HashMap<String, Integer>();
}
map.put("V_TOE_TOE", 10);
map.put("EIGHT_CROSS", 9);
map.put("EAGLE", 8);
map.put("BACKSLIDE", 6);
map.put("PARRAL", 4);
}
public int getScore(String action){
if ("".equals(action) || null == action || map == null) {
return -1;
}
return map.get(action);
}
public static void main(String[] args) {
EnumSingleton e1 = EnumSingleton.enumInstance;
EnumSingleton e2 = EnumSingleton.enumInstance;
// 確認列舉是否只初始化了一次構造方法
System.out.println((e1 == e2) + "|" + (e1 == enumInstance) + "|" + (e2 == enumInstance));
System.out.println("V_TOE_TOE 動作的評分為:" + enumInstance.getScore("V_TOE_TOE") + "分");
}
}