java 設計模式–單例模式推理過程
設計模式(全名:軟件設計模式),是一套反覆使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。 使用設計模式是爲了可重用代碼,讓代碼更容易被他人理解,保證代碼可靠性,程序的重用性。
1. 單例模式
1.1單例模式的特點
- 單例類只能有一個實例。
- 單例類必須自己創建自己唯一的實例。
- 單例類必須給所有其他對象提供這個實例。
1.2 實現過程【懶漢】
- 第一次
/*
* 1. 私有的構造方法
* 共有的話別人一調用就會有新的單例對象,沒法保證單一的實例
* 2. 公有靜態的方法 ---- 用來調用私有的構造方法
* 由於構造方法是私有的,我們要想調用的話,必須在類內有一個方法,這個方法能夠調用這個構造方法,而且在類外也可以使用。
*/
public class SingleTon {
private SingleTon() {}
public static SingleTon getInstance() {
return new SingleTon();
}
}
但是以上代碼有問題:
a . 每次調用 getInstance() 方法返回的是不同的對象(new)。
b. 我們希望其只有一個實例
- 第二次改進
public class SingleTon {
private SingleDog() {}
//使用static是爲了數據的持久性
private static SingleTon instance = null;
public static SingleTon getInstance() {
if (null == instance) {
instance = new SingleTon();
}
return instance;
}
}
這樣調用能基本實現我們的需求,但是仍然存在一個問題,如果在多線程的情況下,有兩個線程同時調用getInstance()方法且滿足if條件(有這個可能偶),這個時候得到的對象不是同一個對象。
- 第三次改進
針對於這個問題,我們直接加synchronized鎖來實現就可以了
public class SingleTon {
private SingleTon() {}
private static SingleTon instance = null;
//只要創建對象就必須進入同步代碼塊
public static synchronized SingleTon getInstance() {
if (null == instance) {
instance = new SingleTon();
}
return instance;
}
}
// 我們爲了進一步優化,可以這樣寫
public class SingleTon {
private SingleTon() {}
private static SingleTon instance = null;
public static SingleTon getInstance() {
// 判定是否爲空,只有是空的時候纔去進入同步代碼部分
if (null == instance) {
synchronized (SingleTon .class) {
//再次檢查,以防有多個都在準備進入同步代碼塊
if (null == instance) {
instance = new SingleTon();
}
}
}
return instance;
}
}
}
第三次改進的代碼又稱爲懶漢單例模式(自己懶得new對象,通過方法new),接下來介紹餓漢單例模式。
1.3 餓漢單例模式
public class SingleTon {
private static SingleTon instance = new SingleTon();
private SingleTon() {}
public static SingleTon instance() {
return instance;
}
}
這個不存在懶漢的多線程安全問題,這個在調用方法的時候就已經存在了唯一的單例類對象,方法只是將這個類對象的地址進行返回。