單例模式(懶)寫法整理(改之前標題“最佳寫法”)

轉載請標明出處:
http://blog.csdn.net/sinat_15877283/article/details/50997664
本文出自: 【溫利東的博客】

之所以想寫這個問題,是因爲之前網上很多都是這樣的代碼:

    private static MyApplication instance;
    public static MyApplication getInstance() {
        if (instance == null) {
            instance = new MyApplication();
        }
        return instance;
    }

這種寫法線程不安全,改進一下,加一個同步鎖(雙重校驗):

    private static MyApplication instance;
    public static MyApplication getInstance() {
         if (instance == null) {
            synchronized (MyApplication.class) {
                if (instance == null) {
                    instance = new MyApplication();
                }
            }
        }
        return instance;
    }

網上這樣的代碼更多,可以很好的工作,這種方式可以很好的降低同步鎖的開銷,但會出現 當線程A和B 執行時,B線程將看到一個還沒有被初始化的對象的問題。
這裏寫圖片描述

實際上,早在JDK1.5就引入volatile關鍵字,所以又有了一種更好的雙重校驗鎖寫法:

    private volatile static MyApplication instance;
    public static MyApplication getInstance() {
        if (instance == null) {
            synchronized (MyApplication.class) {
                if (instance == null) {
                    instance = new MyApplication();
                }
            }
        }
        return instance;
    }

好處:
1.通過雙重檢查鎖定來降低同步的開銷;
2.保證多線程併發執行,採用 volatile 不會出現第二種方法說的那個問題.

還有一種寫法:

class Foo {  
    private static class HelperHolder {
       public static final MyApplication helper = new MyApplication();
    }

    public static MyApplication getHelper() {
        return HelperHolder.helper;
    }
}

內部類能使之 延遲初始化(lazy initialization),並且多線程安全,還能保證高性能。

不是說第一、二種寫法有問題,或者在Android中一定要用第三或第四種寫法,只是告訴大家有更好的寫法。
以上就是我的一點小小記錄,希望對你有所幫助。
轉載請標明出處:
http://blog.csdn.net/sinat_15877283/article/details/50997664
本文出自: 【溫利東的博客】
參考:http://www.infoq.com/cn/articles/double-checked-locking-with-delay-initialization
http://www.ibm.com/developerworks/java/library/j-jtp06197/index.html
http://wiki.jikexueyuan.com/project/java-concurrency/synchronized-and-volatile.html
http://www.race604.com/java-double-checked-singleton/

發佈了38 篇原創文章 · 獲贊 9 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章