Java設計模式之單例模式
阿新 • • 發佈:2021-08-02
所謂類的單例設計模式,就是採取一定的方法保證在整個軟體系統中,對於某個類只能存在一個物件例項,並且該類只提供一個取得其物件例項的方法。
單例模式有8種
餓漢式(靜態常量)
JDK中,java.lang.Runtime原始碼就是採用這種單例模式。
class Singleton{ // 1.構造器私有化(防止外部 new物件) private Singleton(){ } // 2.類的內部建立物件 private final static Singleton instance = new Singleton(); // 3.向外暴露一個靜態的公共方法。getInstance public static Singleton getInstance(){ return instance; } }
優缺點:
- 優點:寫法簡單,在類裝載的時候就完成例項化,避免了執行緒同步的問題。
- 缺點:在類裝載的時候就完成例項化,沒有達到Lazy Loading的效果。如果從未使用過這個例項,則會造成記憶體浪費。
餓漢式(靜態程式碼塊)
class Singleton2{ // 1.構造器私有化(防止外部 new物件) private Singleton2(){ } // 2.類的內部建立物件 private static Singleton2 instance; static { instance = new Singleton2(); } // 3.向外暴露一個靜態的公共方法。getInstance public static Singleton2 getInstance(){ return instance; } }
優缺點同靜態常量。
懶漢式(執行緒不安全)
class Singleton3{
private static Singleton3 instance;
private Singleton3(){
}
public static Singleton3 getInstance(){
if (instance == null){
instance = new Singleton3();
}
return instance;
}
}
優缺點:
- 起到了懶載入的效果,但是隻能在單執行緒下使用。
- 如果在多執行緒下,一個執行緒進入了if(instance == null)判斷語句塊,還未來得及往下執行,另一個執行緒也通過了這個判斷語句,這時便會產生多個例項。所以在多執行緒環境下不可使用這種方式。
懶漢式(執行緒安全,同步方法)
class Singleton4{
private static Singleton4 instance;
private Singleton4(){
}
public static synchronized Singleton4 getInstance(){
if (instance == null){
instance = new Singleton4();
}
return instance;
}
}
優缺點:
- 解決了執行緒不安全的問題
- 效率太低,每個執行緒想獲得類的例項時,執行getInstance()方法都要進行同步。而其實這個方法只執行一次例項化程式碼就夠了,後面的想獲得該類例項直接return就行了。方法進行同步效率太低。
懶漢式(同步程式碼塊)
錯誤寫法,不展示。
雙重檢查
class Singleton6{
private static volatile Singleton6 instance;
private Singleton6(){}
//提供一個靜態的公有方法,加入雙重檢查程式碼,解決執行緒安全問題,同時解決懶載入問題。
public static Singleton6 getInstance(){
if (instance == null){
synchronized (Singleton6.class){
if (instance == null){
instance = new Singleton6();
}
}
}
return instance;
}
}
優缺點:
- Double-Check概念是多執行緒開發中常使用到的,如程式碼中所示,我們進行了兩次if(instance == null)檢查,這樣就可以保證執行緒安全了。
- 執行緒安全,懶載入,效率較高。
靜態內部類
class Singleton7 {
private Singleton7(){}
//靜態內部類,該類中有一個靜態屬性Singleton7
//靜態內部類呼叫時才會裝載,JVM裝載是執行緒安全的過程。
private static class SingletonInstance{
private static final Singleton7 instance = new Singleton7();
}
public static Singleton7 getInstance(){
return SingletonInstance.instance;
}
}
優缺點:
- 採用了類裝載機制來保證初始化例項時只有一個執行緒。
- 靜態內部類方式在Singleton7類被裝載時,並不會立即例項化,而是在需要例項化時呼叫getInstance()才會裝載SingletonInstance類,從而完成Singleton7的例項化。
- 類的靜態屬性只會在第一次載入類的時候初始化,JVM保證了執行緒的安全性。
- 執行緒安全,懶載入,效率高。
列舉
enum Singleton8 {
INSTANCE;
public void sayOK(){
System.out.println("OK");
}
}
public class Singleton8Demo{
public static void main(String[] args){
Singleton8 instance = Singleton8.INSTANCE;
Singleton8 instance2 = Singleton8.INSTANCE;
System.out.println(instance == instance2);
}
}
優缺點:
藉助JDK1.5中新增的列舉類來實現單例模式,不僅能避免多執行緒同步問題,而且還能防止反序列化重新建立新的物件,防止反射,推薦使用。