【設計模式】 單例模式的幾種寫法
阿新 • • 發佈:2019-01-01
單例模式是一種物件建立型模式,使用單例模式,可以保證為一個類只生成唯一的例項物件。也就是說,在整個程式空間中,該類只存在一個例項物件。
在使用懶漢式的單例方法時,如果我們的程式是多執行緒的,可能會出現第一個執行緒判斷不存在,則建立,在建立過程中,第二個執行緒來方法也判斷不存在,同樣建立。這樣就會存在兩個例項,所以將該方法設定為同步方法,看下面的程式碼.
如果我們還想要提高效率,可以試一試雙重檢查.看程式碼.
其實,GoF對單例模式的定義是:保證一個類、只有一個例項存在,同時提供能對該例項加以訪問的全域性訪問方法。
在應用系統開發中,我們常常有以下需求:
-在多個執行緒之間,共享同一個資源或者操作同一個物件
-在整個程式空間使用全域性變數,共享資源
-大規模系統中,為了效能的考慮,需要節省物件的建立時間等等。
因為Singleton模式可以保證為一個類只生成唯一的例項物件,所以這些情況,Singleton模式就派上用場了。
首先是我們熟悉的餓漢式和懶漢式的寫法
//餓漢式
public class Person {
//在類初始化的時候就完成了物件的例項化。
public static final Person person = new Person();
private String name;
//省略get/set方法
//建構函式私有化
private Person() {
}
//提供一個全域性的靜態方法
public static Person getPerson() {
return person;
}
}
//懶漢式 public class Person { private String name; private static Person person; //建構函式私有化 private Person() { } //提供一個全域性的靜態方法 public static Person getPerson() { //在使用該物件的時候如果不存在則進行建立 if(person == null) { person = new Person(); } return person; }
在使用懶漢式的單例方法時,如果我們的程式是多執行緒的,可能會出現第一個執行緒判斷不存在,則建立,在建立過程中,第二個執行緒來方法也判斷不存在,同樣建立。這樣就會存在兩個例項,所以將該方法設定為同步方法,看下面的程式碼.
public synchronized static Person getPerson() {
//在使用該物件的時候如果不存在則進行建立
if(person == null) {
person = new Person();
}
return person;
}
細心的你一定會看到其實只是加入了synchronized來保證方法的同步.
其實在執行這個方法的時候,更多的時候我們是在判斷物件是否存在,而不是在建立物件.將判斷物件是否存在也放到同步方法中,勢必會導致效率降低.所以我們只對例項化方法進行同步.
public static Person getPerson() {
if(person == null) {
synchronized(Person.class){
person = new Person();
}
}
return person;
}
建立方法只能被執行一次,而判斷是否存在例項是要經常執行,如果把同步操作包含判斷則效率會很慢。如果我們還想要提高效率,可以試一試雙重檢查.看程式碼.
public static Person getPerson() {
if(person == null) {
synchronized (Person.class) {
if(person == null) {
person = new Person();
}
}
}
return person;
}
以上就是單例模式的幾種寫法.