實現方法一java
package com.hs.pattern.singleton; /** * 優勢:實現簡單 * 缺點:線程不安全 * 例如:當兩個線程都運行到if( singleton == null ),而singleton確實爲空,則兩個線程都會建立一個實例 * @author Administrator * */ public class Singleton1 { private static Singleton1 singleton = null; private Singleton1(){} public Singleton1 getInstance(){ if( singleton == null ){ singleton = new Singleton1(); } return singleton; } }
實現方法二安全
package com.hs.pattern.singleton; /** * 懶漢模式 * 優勢:線程安全、lazy-loading * 缺點:每次調用getInstance方法都要獲取鎖,效率低 * @author Administrator * */ public class Singleton2 { private static Singleton2 singleton = null; private Singleton2(){} public synchronized Singleton2 getInstance(){ if( singleton == null ){ singleton = new Singleton2(); } return singleton; } }
實現方法三jvm
package com.hs.pattern.singleton; /** * 雙重檢查鎖 * 優勢:只有singleton爲空、須要建立實例時才須要獲取鎖,效率高且線程安全 * 缺點:若是須要實現序列化,則能夠經過序列化、反序列化獲取多個實例 * @author Administrator * */ public class Singleton3 { private static Singleton3 singleton = null; private Singleton3(){} public Singleton3 getInstance(){ if( singleton == null ){ synchronized (Singleton3.class) { if( singleton == null ){ singleton = new Singleton3(); } } } return singleton; } }
實現方案四線程
package com.hs.pattern.singleton; /** * 餓漢模式 * 優勢:實現簡單、線程安全 * 缺點:沒有實現lazy-loading * @author Administrator * */ public class Singleton4 { private static Singleton4 singleton = new Singleton4(); private Singleton4(){} public Singleton4 getInstance(){ return singleton; } }
實現方案五code
package com.hs.pattern.singleton; /** * 靜態內部類 * 優勢:因爲SingletonHolder是靜態的,因此只有首次調用時纔會初始化,由於SingletonHolder是私有內部類, * 因此只有調用Singleton5.getInstance()方法是纔會初始化,從而實現lazy-loading * 缺點:若是須要實現序列化,則能夠經過序列化、反序列化獲取多個實例 * @author Administrator * */ public class Singleton5 { private Singleton5(){} private static class SingletonHolder{ public final static Singleton5 singleton = new Singleton5(); } public static Singleton5 getInstance(){ return SingletonHolder.singleton; } }
實現方案六接口
package com.hs.pattern.singleton; /** * 枚舉類實現單例 * 優勢:對於序列化、反序列化,由於每一個枚舉類型和每一個枚舉變量在jvm中都是惟一的, * 即Java在序列化和反序列化枚舉時作了特殊的規定,枚舉的writeObject、 * readObject、readObjectNoData、writeReplace和readResolve * 等方法是被編譯器禁用的,所以也不存在實現序列化接口後調用readObject會破壞單例的問題。 * 缺點:實現比較複雜 * @author Administrator * */ public class Singleton6 { private Singleton6(){} public static Singleton6 getInstance(){ return SingletonEnum.INSTANCE.getSingleton(); } private static enum SingletonEnum{ INSTANCE; private Singleton6 singleton ; private SingletonEnum(){ singleton = new Singleton6(); } public Singleton6 getSingleton(){ return singleton; } } }