概念介紹
- 什麼是設計模式
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、允許重排序,但是重排序不被其他線程看到。