文章目錄
單例模式
總結:
介紹
保證在整個軟件系統中,對某個類對象只能存在一個實例,並且提供一個取得其對象實例的方法。
餓漢式
靜態常量方式
實現
構造器私有化,屬性位置創建實例的靜態變量, 提供靜態方獲取靜態實例。
public class Single {
// 構造器私有化
private Single(){}
// 靜態實例
private final static Single instance = new Single();
// 靜態方法獲取
private static Single getInstance() {
return instance;
}
}
優點:
寫法比較簡單,在類裝載的時候就完成了實例化。避免了線程同步問題。
缺點:
在類裝載的時候完成實例化,沒有達到Lazy Loading
的效果,如果從始至終沒有使用過這個實例,則會造成內存的浪費。
結論:
靜態代碼塊兒方式
這種方式也是在類加載時候進行實例的new
, 因此優點和缺點和靜態常量方式一致。
實現
package club.fsociety.singleton;
public class Single2 {
// 構造器私有化
private Single2(){ }
// 靜態實例
private static Single2 instance;
// 靜態代碼快兒
static {
instance = new Single2();
}
// 靜態方法獲取
private static Single2 getInstance() {
return instance;
}
}
懶漢式
解決Lazy Loading
的問題。
線程不安全的方式
實現:
package club.fsociety.singleton;
public class Single3 {
// 私有構造器
private Single3(){}
// 靜態成員
private static Single3 instace;
// 獲取實例的方法
private static Single3 getInstace() {
if(null == instace)
instace = new Single3();
return instace;
}
}
優點:
實現了Lazy Loading
。
缺點:
線程不安全,可能多個線程同時判定爲未創建,後進行創建,會導致多創建出來幾個實例。
結論:
瞭解其存在的問題,開發中不要使用。
線程安全方式:
實現
使用了同步代碼塊來修飾獲取實例的方法:
package club.fsociety.singleton;
public class Single3 {
// 私有構造器
private Single3(){}
// 靜態成員
private static Single3 instace;
// 獲取實例的方法
private static synchronized Single3 getInstace() {
if(null == instace)
instace = new Single3();
return instace;
}
}
優點
即解決了餓漢中存在的Lazy Loding
問題,又解決了線程安全問題。
缺點
getInstance
方法頻繁調用下會導致效率地下。
結論
在實際開發中不推薦使用。
DoubleCheck
實現
package club.fsociety.singleton;
public class Single4 {
// 私有構造器
private Single4(){}
// 靜態成員
private static Single4 instace;
// 獲取實例的方法
private static Single4 getInstace() {
if(null == instace) {
synchronized (Single4.class) {
if(null == instace)
instace = new Single4();
}
}
return instace;
}
}
優點
  即解決了Lazy Loading
和 線程安全問題,又避免每次getInstance
的時候都執行一遍同步代碼塊兒。
缺點
 
結論:
強烈推薦使用。
靜態內部類方式
實現方式
外部類被裝載的時候,靜態內部類不會被裝載。當調用外部類獲取靜態內部類方法時候再裝載靜態內部類,且靜態內部類被裝載後會初始化靜態代碼,且線程安全。這樣既能解決線程安全問題,也能解決Lazy Loading
問題。
package club.fsociety.singleton;
public class Single5 {
// 私有化的構造
private Single5(){}
// 靜態內部類
private static class Single5Instance {
private static final Single5 instance = new Single5();
}
// 獲取實例方法
public static Single5 getInstance() {
return Single5Instance.instance;
}
}
優點:
解決線程安全,和LazyLaoding
問題,且效率高。
結論
推薦使用。
枚舉
實現方式:
JDK1.5
中添加的枚舉來實現單例模式,因爲枚舉當中的每個枚舉元素本聲就是自身的一個實例的單例,剛好可以直接藉助來實現單例模式。
public enum Single6 {
INSTANCE;
public void method() {
System.out.println("這是一個實例方法");
}
}
優點
能避免多線程同步問題,而且還能防止反序列化重新創建的對象。其爲最推薦的方式。