設計模式----單例模式(java)

概念介紹

  • 什麼是設計模式
    eg:我們的先人最初在進行房屋建設的時候沒有一個固定的方式,隨着後來建設的房屋越來愈來多,人們慢慢形成了一套建設房子的套路,進過總結之後的方法我們可以認爲是一種“設計模式”;

設計模式可以簡單認爲根據先前的經驗總結出來的套路,是一套被反覆使用、多數人知曉的、經過分類的代碼設計經驗的總結。更多的是反應在思想層面上。

  • 使用設計模式的目的
    使用設計模式是爲了可重用代碼,讓代碼更容易的被他人理解、保證代碼的可靠性;

  • 設計模式有哪些(23種)?

    • 單例模式
    • 工廠模式
    • 建造者模式
    • …..

什麼是單例模式?

eg:你比如說娶媳婦,媳婦只能有一個,如果多了可能就會容易出問題。

有些對象我們只需要一個,比如:
配置文件、工具類、線程池、緩存、日誌對象
如果創造出多個實例,就會導致許多問題出現,比如佔用資源過多,不一致的結果等等..
那麼,我們如何保證應用中某個實例有且只有一個呢~!
我們就可以通過單例模式來實現。

常用單列模式

餓漢模式(Eager Singleton)

/**
 * Created by xiezhongtian on 2017/8/29.
 * 單例模式:
 * 應用場合:有些對象只需要一個就夠了,比如老婆;
 * 作用:保證程序中某個實例只有一個;
 * 類型:餓漢式
 *
 */
public class Singleton {
    //1.將構造方法私有化,不允許外界直接創建對象
    private Singleton(){
    }
    //2.創建類的唯一實例
    private static Singleton instance = new Singleton();

    //3.提供一個用於獲取實例的方法

    public static Singleton getInstance() {
        return instance;
    }
}

懶漢模式(Layz Singleton)

/**
 * Created by xiezhongtian on 2017/8/29.
 * 單例模式:
 * 應用場合:有些對象只需要一個就夠了,比如老婆;
 * 作用:保證程序中某個實例只有一個;
 * 類型:懶漢式、餓漢式
 *
 */
public class Singleton2 {
    //1.2將構造方法私有化,不允許外界直接創建對象
    private Singleton2(){
    }
    //2.2 創建類的唯一實例,並使用 private static 修飾,不實例化;
    private static Singleton2 instance2;

    //3.2 提供一個用於獲取實例的方法,用public static 修飾,在需要時創建實例

    public static Singleton2 getInstance2() {
        if(instance2 == null){
            instance2=new Singleton2();
        }
        return instance2;
    }
}

兩種模式的區別:

  • 餓漢模式加載類時比較慢,運行時獲取對象的速度比較快;
  • 懶漢模式加載類時比較快,運行時獲取對象的速度比較慢;
  • 懶漢就是用時間換空間,餓漢就是用空間換時間
    前者線程安全,後者線程不安全

這裏講的線程不安全,主要是在判斷是否創建了這個實例的代碼塊裏。樓上很多讚的那個,提到的方法叫雙重檢查鎖定。

問題根源是,instance = new Instance()可以分解成三行僞代碼。正常的順序是分配對象的內存空間->初始化對象->設置instance指向剛分配的內存地址。注意第2.3步會被重排序。這時候instance被分配了內存但是沒有初始化。如果這時候有一個線程B來訪問,他判斷instance!=null後調用這個對象時發現對象沒有初始化,就出現bug了~解決方案:1、Instance聲明爲volatile類型。2、允許重排序,但是重排序不被其他線程看到。

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