單态設計模式是使用很廣泛的一個設計模式,這個設計模式的主要目的是通過一定的技術手段來保證在整個軟體系統中隻存在某個類的一個執行個體對象。本文會通過一個Singleton(借鑒别人的)的例子來說明單态設計模式。
Singleton的最初版本
這裡直接給出Singleton的代碼,我們就叫這個版本為1.0版。
//version 1.0
public class Singleton {
private static final Singleton singleton = null;
private Singleton() { }
public static Singleton getInstance() {
if(singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
對上面這個類做個簡要的說明:
1.構造函數是private,這主要是防止在這個類的外部産生該類的執行個體對象。
2.通過一個static的方法getInstance,取得其唯一的執行個體對象。
Singleton的實際版本
或許你認為這樣的代碼就達到我們的目的了,其實上面的程式存在着嚴重的問題,在多線程的情況下,如果有多個線程同時調用getInstance方法,那麼可能就會有多個線程同時通過(singleton == null)的檢查,于是,多個執行個體對象被建立出來了,并且有可能造成記憶體洩露等問題。是以,我們需要通過線程間的同步來解決上面的問題,修改程式代碼,更新為1.1版。
//version 1.1
public class Singleton {
private static final Singleton singleton = null;
private Singleton() { }
public static Singleton getInstance() {
if(singleton == null) {
synchronized(Singleton.class) { //靜态方法的同步鎖為目前類的位元組碼
singleton = new Singleton();
}
}
return singleton;
}
}
雖然上面的程式中通過synchronized實作了線程間的同步,但是還是存在問題,前面說過的,有可能多個線程同時通過(singleton == null)的條件檢查(因為它們并行執行),這樣synchronized方法就将多個并行執行的線程程式設計了串行執行的線程,
一個一個去new,進而得到多個Singleton類的執行個體對象!看來,我們還得把if(singleton == null)也同步了,更新代碼得1.2版。
//version 1.2
public class Singleton {
private static final Singleton singleton = null;
private Singleton() { }
public static Singleton getInstance() {
synchronized(Singleton.class) {
if(singleton == null) {
singleton = new Singleton();
}
}
return singleton;
}
}
至此,我們已經解決了多個線程間的同步問題,保證了在整個的軟體系統中隻有一個Singleton的執行個體對象。然而,還是有一點小問題,我們本來隻想同步new這個操作,然而現在進入getInstance的每個線程都同步了。在單态設計模式中隻要求建立一個對象,其餘的操作都是讀取那個對象,不需要同步。是以上面1.2版中的代碼就會影響程式性能,是以,我們還得改,線上程同步之前加上if(singleton == null),如果對象已經建立,就不需要在同步線程了,更新程式得到1.3版。
//version 1.3
public class Singleton {
private static final Singleton singleton = null;
private Singleton() { }
public static Singleton getInstance() {
if(singleton == null) {
synchronized(Singleton.class) {
if(singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
到此,我們已經寫出了一個很不錯的單态設計模式的例子。希望對大家有所幫助。