***單例模式
### 一奏瞬、什么是單例模式
1侄刽、單例:保證一個類僅有一個實例衷模,并提供一個訪問它的全局訪問點鹊汛。
2、單例模式是一種常用的軟件設(shè)計模式之一阱冶,其目的是保證整個應(yīng)用中只存在類的唯一個實例刁憋。
比如我們在系統(tǒng)啟動時,需要加載一些公共的配置信息木蹬,對整個應(yīng)用程序的整個生命周期中都可見且唯一至耻,這時需要設(shè)計成單例模式。如:spring容器镊叁,session工廠尘颓,緩存,數(shù)據(jù)庫連接池晦譬,網(wǎng)絡(luò)連接池等等疤苹。
### 二、如何保證實例的唯一
1敛腌、防止外部初始化
2卧土、由類本身進(jìn)行實例化
3、保證實例化一次
4像樊、對外提供獲取實例的方法
5尤莺、線程安全
### 三、幾種單利模式的實現(xiàn)和比較
1生棍、餓漢模式
“因為餓颤霎,所以要立即吃飯,刻不容緩”,在定義類的靜態(tài)私有變量同時進(jìn)行實例化捷绑。
```java
public class Singleton {
private static final Singleton singleton = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
```
當(dāng)然上面的餓漢模式中的對象韩脑,你也可以放在靜態(tài)代碼塊中進(jìn)行初始化
```java
public class Singleton {
private static? Singleton singleton = null;
static{
singleton = new Singleton()
}
private Singleton() {
}
public static Singleton getInstance() {
return singleton;
}
}
```
2、懶漢模式
“因為懶粹污,所以都忘記了創(chuàng)建初始對象”段多,在定義類的靜態(tài)私有變量,不進(jìn)行初始化壮吩。
```java
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
```
3进苍、如果使涉及到線程問題,上面的例子并不能滿足您的要求了鸭叙,因為線程不安全觉啊,那如何實現(xiàn)線程安全的單例模式呢,上代碼(懶漢)
```java
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static? Singleton getInstance() {
if (singleton == null) {? //? 1號
synchronized (Singleton.class) {
if (singleton == null) {? //2號
singleton = new Singleton();
}
}
}
return singleton;
}
}
```
可能您會疑惑沈贝,為什么要判斷兩次空杠人?舉個例子,現(xiàn)在有兩個線程A和B宋下。假設(shè)A先執(zhí)行嗡善,B后執(zhí)行,此時同時運行到1號備注学歧,此時的singleton ==? null罩引。下一刻A繼續(xù)運行,B等待枝笨,當(dāng)A執(zhí)行完成后singleton !=? null袁铐。所以當(dāng)B執(zhí)行的時候不需要再創(chuàng)建。所以需要兩次判斷横浑。
4剔桨、靜態(tài)內(nèi)部類。優(yōu)點:既避免了同步帶來的性能損耗伪嫁,又能夠延遲加載
```java
public class Singleton {
private Singleton() {
}
private static class SingletonHolder {
private static final Singleton singleton = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.singleton;
}
}
```
5领炫、枚舉。天然線程安全张咳,可防止反射生成實例帝洪。
```java
public enum Singleton {
INSTANCE;
public void init() {
System.out.println("資源初始化。脚猾。葱峡。");
}
}
```
### 四、總結(jié)
優(yōu)點:該類只存在一個實例龙助,節(jié)省系統(tǒng)資源砰奕;對于需要頻繁創(chuàng)建銷毀的對象蛛芥,使用單例模式可以提高系統(tǒng)性能。
缺點:不能外部實例化(new)军援,調(diào)用人員不清楚調(diào)用哪個方法獲取實例時會感到迷惑仅淑,尤其當(dāng)看不到源代碼時。
### 附錄:后續(xù)將會推出一系列設(shè)計模式文章胸哥,請關(guān)注我的博客 [lueans](https://lueans.github.io)涯竟,希望能幫助到大家