本文講解GOF-23種設計模式其中的單例模式。
單例模式說難吧,其實只有那麼幾句代碼。
說簡單吧,其實也要深入理解才能瞭解它的原理,廢話少說,看代碼
一、餓漢式寫法
/**
* 作者: Created by AdminFun
* 郵箱: [email protected]
* 描述: 餓漢式單例
* 這種寫法是最簡單、也算是比較完美的寫法,但是這種寫法有一些缺點:
* 1、instance的初始化是在類加載的時候完成的,所以不管你用不用都會初始化,可能造成資源浪費。
* 2、如果初始化instance需要依賴其他的數據,那麼這裏就不能保證在初始化之前準備好。
* 相比於餓漢式寫法,有一種更加優美的寫法,那就是懶漢式寫法 {@link CarHelper1}
*/
public class CarHelper {
private static final CarHelper instance = new CarHelper();
private CarHelper() {
}
public static CarHelper getInstance() {
return instance;
}
}
二、懶漢式寫法
/**
* 作者: Created by AdminFun
* 郵箱: [email protected]
* 描述: 懶漢式單例
*/
public class CarHelper1 {
/**
* volatile 關鍵字的作用是禁止指令重排,用volatile修飾之後,
* 對instance的讀寫操作就有一個內存保障,保證在完成寫之前不會被調用讀。
* <p>
* 想要了解上面一句話,則需要了解JVM中實例化執行過程:
* 1、分配內存
* 2、初始化成員變量,形成實例
* 3、將對象指針指向該內存
* 在多線程操作的時候,以上3個步驟可能會被交叉執行,造成錯誤內存,volatile就是用來解決這個問題的。
* 不過在平常的一般開發中我們並沒有這麼嚴格的要求單例寫法,因爲在APP開發中很少遇到多線程操作或者我們根本不在乎這個問題
*/
private static volatile CarHelper1 instance;
/**
* 構造方法私有是保證不被外部調用
*/
private CarHelper1() {
// 可以根據需求初始化自己需要的內容
}
/**
* 使用雙重判斷 + 線程鎖
* 雙重判斷:是爲了提升效率,畢竟synchronized算是一個重量級線程鎖,如果能在線程鎖外面就攔截多線程,則會降低內存消耗
* 線 程 鎖:保證只能有1個線程執行鎖內操作
*/
public static CarHelper1 getInstance() {
if (instance == null) {
synchronized (CarHelper1.class) {
if (instance == null) {
instance = new CarHelper1();
}
}
}
return instance;
}
}