每次引用類別都只會產出相同的物件
適合用在: 執行緒池(thread pool),快取區(cache),對話盒、處理對話設定和登錄的物件,和驅動程式溝通的物件。
作法
假如有一個類別叫做MyClass,現在要讓MyClass變成獨體模式,讓外面的類別只能透過 MyClass.getInstance() 取得MyClass物件。
1  | public class MyClass {  | 
其他類別要取用MyClass
1  | public static void main(String args[]) {  | 
多執行緒下獨體模式會遇到的狀況
假如有兩個thread(thread 1和thread 2),同時要跟MyClass取得物件,但會面臨thread1和thread2會取得不同的MyClass物件,情況如下:

解法一:只要把getInstance()給同步化 (會有效能不佳的狀況,可能造成效率下降100倍)
1  | public class MyClass {  | 
但我們只需要第一次進入getInstance才進行同步化就好,不然其他次要取得uniqueInstnace都得變成同步的方式,造成取用Instance的緩慢
解法二:率先建立實體,不要等到有人呼叫getInstance才new出MyClass實體
1  | public class MyClass {  | 
此作法依賴JVM載入此類別時,馬上建立此唯一的獨體物件,JVM保證在任何執行緒存取uniqueInstnace靜態變數之前,一定先建立此實體
解法三:利用 “雙重檢查上鎖” 在getInstance()中減少使用同步化
利用雙重檢查上鎖,首先檢查是否實體已經建立了,
若沒有,“才”進行同步化,如此一來只有第一次進入getInstance才同步化,才是我們所想要的。
public class MyClass {
    // volatile為Java 6之後才有的關鍵字,能夠使執行緒們取得相同的uniqueInstance
    private volatile static MyClass uniqueInstance;
    
    private MyClass() {}
    
    public static MyClass getInstance() {
        // 只有第一次才徹底執行以下程式碼 
        // 當執行緒遇到被宣告成volatile的uniqueInstnace,會變得謹慎
        if(uniqueInstance == null) {
            synchronized(MyClass.class) {
                // 再檢查一次,若為null則new MyClass();
                if(uniqueInstance == null) {
                    uniqueInstance = new MyClass();
                }
            }
        }
        return uniqueInstance;
    }
}