不推薦使用Singleton1和Singleton2,Singleton3基本可以滿足需求,Singleton5支援消極式載入,但是實現稍麻煩,Effective Java 作者推薦通過枚舉實現單例,自動支援序列化機制,防止還原序列化重新建立新的對象,絕對防止多次執行個體化
通過枚舉實現單例
package com.basic.designpatterns.create.singleton;/** * 單例 * * @author chichuduxing * @date 2017年2月4日 下午4:40:22 */class Resource {// 具體業務.public void doSomeThing() {System.out.println("working");}}/** * 通過枚舉類實現(枚舉類中構造必須是私人的) 支援安全執行緒,支援序列化 */public enum EnumSingleton {INSTANCE;private Resource instance = null;private EnumSingleton() {instance = new Resource();}public Resource getInstance() {return instance;}}
通過枚舉實現單例,但是不暴露細節的單例類
package com.basic.designpatterns.create.singleton;/** * @author chichuduxing * @date 2017年4月3日 下午7:54:42 */public class EnumFactory {/** * 對外的擷取單例的方法 * * @return 單例對象 */public static SingResource getInstance() {return EnumSingleton.INSTANCE.getInstance();}/** * 通過枚舉類實現(枚舉類中構造必須是私人的) 支援安全執行緒,支援序列化 */private enum EnumSingleton {INSTANCE;private SingResource instance = null;private EnumSingleton() {instance = new SingResource();}public SingResource getInstance() {return instance;}}/** * 測試方法 * * @param args */public static void main(String[] args) {EnumFactory.getInstance().doSomeThing();}}/** * 具體實現功能的單例類 */class SingResource {public SingResource() {}// 具體業務.public void doSomeThing() {System.out.println("working");}}
其他若干種實現方式
package com.basic.designpatterns.create.singleton;/** * 單例模式 * * @author chichuduxing * @date 2017年2月4日 上午11:19:02 *//** * 懶漢式,線程不安全 */class Singleton1 {private Singleton1() {}private static Singleton1 instance = null;public static Singleton1 getInstance() {if (null == instance) {return new Singleton1();}return instance;}}/** * 懶漢式,安全執行緒 效率低 */class Singleton2 {private Singleton2() {}private static Singleton2 instance = null;public static synchronized Singleton2 getInstance() {if (null == instance) {return new Singleton2();}return instance;}}/** * 餓漢式,(單個ClassLoader時安全執行緒) 無鎖,安全執行緒,但是類載入時就會new對象. */class Singleton3 {private Singleton3() {}private static Singleton3 instance = new Singleton3();public static Singleton3 getInstance() {return instance;}}/** * 雙重鎖校正 懶漢式,安全執行緒.需要加volatile關鍵字</br> * 因為instance = new Singleton4();並不是原子的操作,</br> * 如果處理器進行重排序後可能早晨instance雖然不為null了,但是執行個體還沒初始化</br> */class Singleton4 {private Singleton4() {}// 必選加volatile關鍵字private volatile static Singleton4 instance = null;public static Singleton4 getInstance() {if (instance == null) {synchronized (Singleton4.class) {if (null == instance) {instance = new Singleton4();}}}return instance;}}/** * 內部類,內部類是延時載入的,只會在第一次使用時載入,不使用就不載入。 懶漢式,安全執行緒. */class Singleton5 {private Singleton5() {}static class InnerSingleton {private static final Singleton5 instance = new Singleton5();}public static final Singleton5 getInstance() {return InnerSingleton.instance;}}public class SingletonPatternDemo {// 推薦EnumSingleton// 其次Singleton5public static void main(String[] args) {EnumSingleton.INSTANCE.getInstance().doSomeThing();}}