為了確保我們只會有一個instance,所以使用private
的建構子,這樣其他類別就沒辦法從外部去產生新的instance。getInstance()
則是在每次外部需要用到此類別物件時會被用Singleton.getInstance()
呼叫,就會有global variable 的效果,若尚未產生instance,就會建構它。
(參考下方餓漢模式)
餓漢模式 Eagerly Instantiation
public class Singleton{
private static Singleton uniqueInstance;
private Singleton(){}
public static Singleton getInstance(){
return uniqueInstance;
}
}
懶漢模式 Lazy Instantiation
public class Singleton{
private static Singleton uniqueInstance;
private Singleton(){}
public static Singleton getInstance(){
//先檢查是否已經建構好,如果還沒有instance,就new一個
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
雙重鎖模式
public class Singleton{
//第一次檢查: 用volatile
private volatile static Singleton uniqueInstance;
private Singleton(){}
public static Singleton getInstance(){
//第二次檢查
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
synchronized
:如果有多個執行緒(thread)要共用同一個方法(method)或區塊(block),可以讓他們依序執行,避免相互影響。需等待前一個執行緒完成,很大程度上影響performance,所以要謹慎使用。volatile
: 讀取變數的主要記憶體而不是變數的暫存記憶體(cache)Disclaimer
因為讀的是原文版,所以難免會有翻譯詞不達意或是專有名詞上的差異,有錯誤的話歡迎在留言區一起交流!