在開發過程中常常會有這樣的需求:
- 在多個線程之間,共享同一個資源或者操作同一個對象。
- 在整個程序空間使用全局變量,共享資源。
這樣就需要保證一個類只生成一個唯一的實例對象。這就是單例模式了。
GoF對單例模式的定義是:保證一個類、只有一個實例存在,同時提供能對該實例加以訪問的全局訪問方法。
下面來看結構圖(摘至 程傑 大話設計模式)
設計模式類時要注意兩點:
- 構造方法需要private,防止外界利用new 創建類實例。
- 提供一個靜態方法,爲本類實例唯一的全局訪問點。
單例模式有兩種創建方式:
- 餓漢式:利用靜態初始化的方式,在類加載時就將自己實例化。靜態方法返回這唯一的實例。
- 懶漢式:在第一次使用時,經過判斷後,纔會將自己實例化。在多線程場景下,需加鎖和雙重檢查保證只實例化一次。
下面來看代碼吧
1、餓漢式
public class Person {
// 靜態初始化
public static final Person person = new Person();
//構造函數私有化
private Person() {
}
//提供一個全局的靜態方法
public static Person getPerson() {
return person;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2、懶漢式
public class Person{
private static Person person;
//構造函數私有化
private Person4() {
}
//提供一個全局的靜態方法
public static Person4 getPerson() {
if(person == null) {
synchronized (Person.class) {
if(person == null) {
person = new Person();
}
}
}
return person;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
總結:
當遇到需要保證一個類只生成一個唯一的實例對象的場景時,就可以使用單例模式了。餓漢式類加載時初始化實例,提前佔用系統資源;懶漢式需要考慮多線程訪問安全問題。所以需要根據實際的業務場景來選擇。