單例模式

參考連接:html

http://www.runoob.com/design-pattern/singleton-pattern.htmljava

1. 什麼是單例模式

一個類只有一個實例,每次都返回相同實例安全

2. 什麼狀況下以及如何使用單例模式

須要控制實例數目時可選擇使用該模式,建議使用靜態內部類實現,只有在調用getInstance時才實例化,實現了Lazy初始化,也是多線程安全。利用classloader機制保證初始化instance時只有一個線程。多線程

單俐對象每每存在於DAO層,例如SessionFactory函數

3. 使用單例模式的好處

在內存中只有一個實例,減小內存開銷。spa

單俐模式的幾種實現方式

1. 懶漢式,線程不安全

/**
 * Created by liang on 2018/5/8.
 */
public class SingletonDemo {

    private static SingletonDemo instance;

    // 構造函數私有化
    private SingletonDemo() {}

    public static SingletonDemo getInstance() {
        if (instance == null) {
            instance = new SingletonDemo();
        }

        return instance;
    }

}

2. 懶漢式,線程安全

/**
 * 線程安全的單俐模式實現
 * Created by liang on 2018/5/8.
 */
public class ThreadSafeSingletonDemo {

    private static ThreadSafeSingletonDemo instance;

    private ThreadSafeSingletonDemo() {}

    public static  synchronized ThreadSafeSingletonDemo getInstance() {
        if (instance == null) {
            instance = new ThreadSafeSingletonDemo();
        }

        return instance;
    }
}

3. 靜態內部類<推薦>

/**
 * 使用靜態內部類
 * 在調用getInstance()時才加載該單俐類,這種方法也是線程安全的
 * Created by liang on 2018/5/8.
 */
public class StaticInnerClassSingletonDemo {

    private static class SingletonHolder {
        private static StaticInnerClassSingletonDemo instance = new StaticInnerClassSingletonDemo();
    }

    private StaticInnerClassSingletonDemo() {}

    public static StaticInnerClassSingletonDemo getInstance() {
        return SingletonHolder.instance;
    }
}

4. 雙重校驗鎖

/**
 * 雙重鎖校驗
 * Step 1: 線程A訪問getInstance()方法,由於單俐尚未實例化,因此進入了鎖定塊
 * Step 2: 線程B訪問getInstance()方法,得以訪問接下來的代碼塊,而接下來代碼塊已經被線程A鎖定
 * Step 3: 線程A進入下一判斷,由於單俐尚未實例化,因此進行單俐實例化,成功實例化後退出代碼塊,解除鎖定
 * Step 4: 線程B進入接下來的代碼塊,鎖定線程,進入下一判斷,由於已經實例化,退出代碼塊,解除鎖定。
 * Step 5: 線程A獲取到了單俐實例並返回,線程B沒有獲取到單俐返回Null
 * Created by liang on 2018/5/8.
 */
public class DoubleValidateSingletonDemo {

    // 每次都返回最新的值
    private volatile static DoubleValidateSingletonDemo instance;

    private DoubleValidateSingletonDemo() {}

    public static DoubleValidateSingletonDemo getInstance() {
        if (instance == null) {
            synchronized (DoubleValidateSingletonDemo.class) {
                if (instance == null) {
                    instance = new DoubleValidateSingletonDemo();
                }
            }
        }
        return instance;
    }
}
相關文章
相關標籤/搜索