實現方法一
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;
}
}
實現方法三
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;
}
}
實現方案五
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;
}
}
}