MartinYeung
MartinYeung

Love life Love IT IT blog: https://ithelp.ithome.com.tw/users/20119569

Java - singleton pattern 的介紹及使用

閱讀時間: 15分鐘

單例模式 (singleton pattern)

它存在的目的是可以限制物件(Object)產生的數量,只容許產生一個物件(Objest)。

那就是只有一個實例(Instance)。

往後每次調用都是指向相同的物件(Object)。

public class Singleton{  
    private static Singleton uniqueInstance;  
    // 使用private Consructor 確保類別Singleton 的物件(Object)只能透過 API – method : getInstance()。
private Singleton()
{
	// 這裡可以有很多code,所以建立物件(Object)可能需要很多資源/時間。
}
	// 因為Constructor已經private,所以需要以下方法讓其他程式調用這個類別。public static Singleton getInstance() {  
		// 第一次被呼叫時,才建立物件(Object)if(uniqueInstance == null ) {
uniqueInstance = new Singleton();
}  
        return uniqueInstance;  
    }  
}  

以上程式在某些情況運行時是沒問題,但如果是在多執行緒(Multi Thread)的情況下呼叫getInstance(),可能第一個執行緒(Thread)跑到instance = new Singleton()時,另一個執行緒(Thread)在 if(uniqueInstance==null) 判斷時也進入迴圈(loop), 最後同一時間產生了多於一個的物件(Object)。

為了解決這個情況,我們需要對剛才的程式進行修改。

在程式內加上同步(synchronized)關鍵字

public class Singleton{  
    private static Singleton uniqueInstance;  
    // 使用private Consructor 確保類別Singleton 的物件(Object)只能透過 API – method : getInstance()。
private Singleton()
{
	// 這裡可以有很多code,所以建立物件(Object)可能需要很多資源/時間。
}
	// 因為Constructor已經private,所以需要以下方法讓其他程式調用這個類別。public static synchronized Singleton getInstance() {  
		// 使用 synchronized 關鍵字避免多於一個Thread 進入if(uniqueInstance == null ) {
uniqueInstance = new Singleton();
}  
        return uniqueInstance;  
    }  
}  

不過同步(synchronized)關鍵字會導致程式的執行效能會變差,(不適合用於像伺服器這種有很多執行緒(Multi Thread)的程式上)。

所以可以使用雙重檢查鎖定模式(Double-check Locking),加快程式的效能。

雙重檢查鎖定模式(Double-check Locking)

就是將synchronized搬到getInstance方法內。

public class Singleton{  
    private static Singleton uniqueInstance;  
    // 使用private Consructor 確保類別Singleton 的物件(Object)只能透過 API – method : getInstance()。
private Singleton()
{
	// 這裡可以有很多code,所以建立物件(Object)可能需要很多資源/時間。
}
	// 因為Constructor已經private,所以需要以下方法讓其他程式調用這個類別。public static Singleton getInstance() {  
		// 使用 synchronized 關鍵字避免多於一個Thread 進入if(instance == null){
            synchronized(Singleton.class){
                if(instance == null){
                    instance = new Singleton();
                }    
            }
        }         return uniqueInstance;  
    }  
}  


CC BY-NC-ND 2.0

Like my work?
Don't forget to support or like, so I know you are with me..

Loading...

Comment