1.餓漢模式(線程安全,調用效率高,但是不能延時加載):

package com.yanwu.www.demo; /* * 測試單例模式 * * 餓漢模式 * * @author harvey * */ public class SingletonDemo1 { //類初始化時立即加載對象(沒有延遲加載的優勢),天然的線程安全 private static SingletonDemo1 instance=new SingletonDemo1(); //構造器私有化 private SingletonDemo1(){} //方法沒有同步,調用效率高 public static SingletonDemo1 getInstance(){ return instance; } }
2.懶漢模式(線程安全,調用效率不高,但是能延時加載):

package com.yanwu.www.demo; /* *測試單例模式 * *懶漢模式 * *@author harvey * */ public class SingletonDemo2 { //類初始化時,不初始化這個對象(延時加載,真正用的時候再創建) private static SingletonDemo2 instance; //構造器私有化 private SingletonDemo2(){} //方法同步,調用效率低 public static synchronized SingletonDemo2 getInstance(){ if(instance==null){ instance=new SingletonDemo2(); } return instance; } }
3.雙重檢測鎖模式(由於JVM底層模型原因,偶爾會出問題,不建議使用):

package com.yanwu.www.demo; /* * 單例模式 * * 雙重檢測鎖式 * * 由於JVM底層內部模型原型,偶爾會出現問題,不建議使用 * * @author harvey */ public class SingletonDemo5 { private volatile static SingletonDemo5 SingletonDemo5; private SingletonDemo5() { } public static SingletonDemo5 newInstance() { if (SingletonDemo5 == null) { synchronized (SingletonDemo5.class) { if (SingletonDemo5 == null) { SingletonDemo5 = new SingletonDemo5(); } } } return SingletonDemo5; } }
4.靜態內部類式(線程安全,調用效率高,可以延時加載):

package com.yanwu.www.demo; /* * 單例模式 * * 靜態內部類的實現 * * 1.外部類沒有static 屬性,不會像餓漢一樣立即加載對象 * * 2.只有真正調用getInstance()才會加載靜態內部類,加載時是線程安全的 * * 3.兼並延時調用和並發高效調用 * * @author harvey * */ public class SingletonDemo3 { private static class SingletonClassInstance{ private static final SingletonDemo3 instance=new SingletonDemo3(); } private SingletonDemo3(){} public static SingletonDemo3 getInstance(){ return SingletonClassInstance.instance; } }
5.枚舉類(線程安全,調用效率高,不能延時加載,可以天然的防止反射和反序列化調用):

package com.yanwu.www.demo; /* * 單例模式 * * 枚舉式實現 * * 1.避免了反射和反序列化的漏洞 * * 2.沒有延時加載的效果 * * @author harvey */ public enum SingletonDemo4 { //枚舉元素本身就是單例 INSTANCE; //添加自己需要的操作 public void singletonOperation(){ } }
如何選用:
-單例對象 占用資源少,不需要延時加載,枚舉 好於 餓漢
-單例對象 占用資源多,需要延時加載,靜態內部類 好於 懶漢式