設計模式之單例模式
單例模式就是指整個應用中只能存在一個實例。單例類的創建有三種方式。就這三種方式可以作一個比較:
第一種:在聲明變量出實例化對象(也叫 餓漢式 單例模式)代碼如下:
package com.zds.pattern.singleton;
/**
* @author sam E-mail:ashan8888@163.com
* @version 1.0
*/
public class SingletonA {
private static SingletonA singletonA = new SingletonA();
private SingletonA(){
System.out.println("餓漢式");
}
public static SingletonA getInstance(){
return singletonA;
}
}
第二種:把對象的創建放到方法里邊去(也較 懶漢式 單例模式)代碼如下:
package com.zds.pattern.singleton;

/**
* @author sam E-mail:ashan8888@163.com
* @version 1.0
*/
public class SingletonB {
private static SingletonB singletonB;

private SingletonB(){
System.out.println("懶漢式");
}
synchronized public static SingletonB getInstance() {

if (singletonB == null) {
singletonB = new SingletonB();
}
return singletonB;
}
}
第三種:另類懶漢式方式:代碼如下:
package com.zds.pattern.singleton;
/**
* @author sam E-mail:ashan8888@163.com
* @version 1.0
*/
public class SingletonC {
static class SingletonHolder {
static SingletonC instance = new SingletonC();
}
private SingletonC(){
System.out.println("另類懶漢式");
}
public static SingletonC getInstance() {
return SingletonHolder.instance;
}
}
他們之間有什么有缺點呢?? 先來看第一種方式:懶漢式
優點:在初始化的時候創建對象,調用getInstance的時候,沒有同步方法,性能較高。
缺點:可能導致數據還未初始完就創建了對象,故有可能對象數據初始不正確。
上邊第一段代碼例子太簡單了,看不成任何問題,那么來寫一個可能產生問題的例子看看:代碼如下:
package com.zds.pattern.singleton;

/**
* @author sam E-mail:ashan8888@163.com
* @version 1.0
*/
public class SingletonAa {
private static SingletonAa singletonAa = new SingletonAa();

public static String name = "sam";

public static String password;
static {
password = "tiger";
}
private SingletonAa(){
if(name.equals("sam")) System.out.println("name is ok");
if(password.equals("tiger")) System.out.println(" password is ok");
}

public static SingletonAa getInstance() {
return singletonAa;
}
}
第一種:在聲明變量出實例化對象(也叫 餓漢式 單例模式)代碼如下:


















第二種:把對象的創建放到方法里邊去(也較 懶漢式 單例模式)代碼如下:






















第三種:另類懶漢式方式:代碼如下:


















他們之間有什么有缺點呢?? 先來看第一種方式:懶漢式
優點:在初始化的時候創建對象,調用getInstance的時候,沒有同步方法,性能較高。
缺點:可能導致數據還未初始完就創建了對象,故有可能對象數據初始不正確。
上邊第一段代碼例子太簡單了,看不成任何問題,那么來寫一個可能產生問題的例子看看:代碼如下:


























寫到這個地方,是不是能看出點眉目了,呵呵,上邊代碼是不是會拋出:java.lang.NullPointerException異常,為什么呢,很簡單,我們知道
類的加載過程是什么: 裝載----驗證 ---準備---解析---初始化。初始化之前,類加載器會把所有變量都默認為對應類型的默認值。復合類型變量是不是為null,而在初始的時候,上邊的第一條語句就new了本身,在進入構造器函數的時候,是不是就產生了錯誤。
第二種創建方式的優缺點:
優點:避免了第一種方式可能產生的錯誤。
缺點:不利于用在多線程上,因為他使用了鎖,這樣在資源上有很大浪費。
后來有人提出了雙檢查單例模式,參考資料在:http://www.ibm.com/developerworks/java/library/j-dcl.html?dwzone=java
第三種創建方式的優缺點:(Bob lee創建的)
優點: 綜合了上訴兩種方法的優點,故,我比較推薦使用這種方式;
posted on 2007-12-21 15:03 sam.chuan.yang 閱讀(1757) 評論(2) 編輯 收藏 所屬分類: 23設計模式的理解