設(shè)計模式之單例模式
單例模式就是指整個應(yīng)用中只能存在一個實例。單例類的創(chuàng)建有三種方式。就這三種方式可以作一個比較:
第一種:在聲明變量出實例化對象(也叫 餓漢式 單例模式)代碼如下:
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;
}
}
第二種:把對象的創(chuàng)建放到方法里邊去(也較 懶漢式 單例模式)代碼如下:
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;
}
}
他們之間有什么有缺點呢?? 先來看第一種方式:懶漢式
優(yōu)點:在初始化的時候創(chuàng)建對象,調(diào)用getInstance的時候,沒有同步方法,性能較高。
缺點:可能導(dǎo)致數(shù)據(jù)還未初始完就創(chuàng)建了對象,故有可能對象數(shù)據(jù)初始不正確。
上邊第一段代碼例子太簡單了,看不成任何問題,那么來寫一個可能產(chǎn)生問題的例子看看:代碼如下:
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;
}
}
第一種:在聲明變量出實例化對象(也叫 餓漢式 單例模式)代碼如下:


















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






















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


















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


























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