1. 程式人生 > >【設計模式】 單例模式的幾種寫法

【設計模式】 單例模式的幾種寫法

          單例模式是一種物件建立型模式,使用單例模式,可以保證為一個類只生成唯一的例項物件。也就是說,在整個程式空間中,該類只存在一個例項物件。

    其實,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;
	}
      

       以上就是單例模式的幾種寫法.