青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

逛奔的蝸牛

我不聰明,但我會很努力

   ::  :: 新隨筆 ::  ::  :: 管理 ::

轉(zhuǎn)載請注明出處:http://cantellow.javaeye.com/blog/838473

 

第一種(懶漢,線程不安全):

 

Java代碼 
  1. public class Singleton {  
  2.     private static Singleton instance;  
  3.   
  4.     public static Singleton getInstance() {  
  5.     if (instance == null) {  
  6.         instance = new Singleton();  
  7.     }  
  8.     return instance;  
  9.     }  
  10. }  

 這種寫法lazy loading很明顯,但是致命的是在多線程不能正常工作。

第二種(懶漢,線程安全):

 

Java代碼 
  1. public class Singleton {  
  2.     private static Singleton instance;  
  3.   
  4.     public static synchronized Singleton getInstance() {  
  5.     if (instance == null) {  
  6.         instance = new Singleton();  
  7.     }  
  8.     return instance;  
  9.     }  
  10. }  

 這種寫法能夠在多線程中很好的工作,而且看起來它也具備很好的lazy loading,但是,遺憾的是,效率很低,99%情況下不需要同步。

第三種(餓漢):

 

Java代碼 
  1. public class Singleton {  
  2.     private static Singleton instance = new Singleton();  
  3.   
  4.     public static Singleton getInstance() {  
  5.     return instance;  
  6.     }  
  7. }  

 這種方式基于classloder機(jī)制避免了多線程的同步問題,不過,instance在類裝載時就實例化,雖然導(dǎo)致類裝載的原因有很多種,在單例模式中大多數(shù)都是調(diào)用getInstance方法, 但是也不能確定有其他的方式(或者其他的靜態(tài)方法)導(dǎo)致類裝載,這時候初始化instance顯然沒有達(dá)到lazy loading的效果。

第四種(漢,變種):

 

Java代碼 
  1. public class Singleton {  
  2.     private Singleton instance = null;  
  3.     static {  
  4.     instance = new Singleton();  
  5.     }  
  6.   
  7.     public static Singleton getInstance() {  
  8.     return this.instance;  
  9.     }  
  10. }  

 

 表面上看起來差別挺大,其實更第三種方式差不多,都是在類初始化即實例化instance。

第五種(靜態(tài)內(nèi)部類):

 

Java代碼 
  1. public class Singleton {  
  2.     private static class SingletonHolder {  
  3.     private static final Singleton INSTANCE = new Singleton();  
  4.     }  
  5.   
  6.     public static final Singleton getInstance() {  
  7.     return SingletonHolder.INSTANCE;  
  8.     }  
  9. }  

 

這種方式同樣利用了classloder的機(jī)制來保證初始化instance時只有一個線程,它跟第三種和第四種方式不同的是(很細(xì)微的差別):第三種和第四種方式是只要Singleton類被裝載了,那么instance就會被實例化(沒有達(dá)到lazy loading效果),而這種方式是Singleton類被裝載了,instance不一定被初始化。因為SingletonHolder類沒有被主動使用,只有顯示通過調(diào)用getInstance方法時,才會顯示裝載SingletonHolder類,從而實例化instance。想象一下,如果實例化instance很消耗資源,我想讓他延遲加載,另外一方面,我不希望在Singleton類加載時就實例化,因為我不能確保Singleton類還可能在其他的地方被主動使用從而被加載,那么這個時候?qū)嵗?/span>instance顯然是不合適的。這個時候,這種方式相比第三和第四種方式就顯得很合理。

第六種(枚舉):

 

Java代碼 
  1. public enum Singleton {  
  2.     INSTANCE;  
  3.     public void whateverMethod() {  
  4.     }  
  5. }  

 

 這種方式是Effective Java作者Josh Bloch 提倡的方式,它不僅能避免多線程同步問題,而且還能防止反序列化重新創(chuàng)建新的對象,可謂是很堅強(qiáng)的壁壘啊,不過,個人認(rèn)為由于1.5中才加入enum特性,用這種方式寫不免讓人感覺生疏,在實際工作中,我也很少看見有人這么寫過。

第七種(雙重校驗鎖):

 

Java代碼 
  1. public class Singleton {  
  2.     private volatile static Singleton singleton;  
  3.   
  4.     public static Singleton getSingleton() {  
  5.     if (singleton == null) {  
  6.         synchronized (Singleton.class) {  
  7.         if (singleton == null) {  
  8.             singleton = new Singleton();  
  9.         }  
  10.         }  
  11.     }  
  12.     return singleton;  
  13.     }  
  14. }  

 

 這個是第二種方式的升級版,俗稱雙重檢查鎖定,詳細(xì)介紹請查看:http://www.ibm.com/developerworks/cn/java/j-dcl.html

在JDK1.5之后,雙重檢查鎖定才能夠正常達(dá)到單例效果。

 

總結(jié)

有兩個問題需要注意:

1.如果單例由不同的類裝載器裝入,那便有可能存在多個單例類的實例。假定不是遠(yuǎn)端存取,例如一些servlet容器對每個servlet使用完全不同的類裝載器,這樣的話如果有兩個servlet訪問一個單例類,它們就都會有各自的實例。

2.如果Singleton實現(xiàn)了java.io.Serializable接口,那么這個類的實例就可能被序列化和復(fù)原。不管怎樣,如果你序列化一個單例類的對象,接下來復(fù)原多個那個對象,那你就會有多個單例類的實例。

對第一個問題修復(fù)的辦法是:

 

Java代碼 
  1. private static Class getClass(String classname)      
  2.                                          throws ClassNotFoundException {     
  3.       ClassLoader classLoader = Thread.currentThread().getContextClassLoader();     
  4.       
  5.       if(classLoader == null)     
  6.          classLoader = Singleton.class.getClassLoader();     
  7.       
  8.       return (classLoader.loadClass(classname));     
  9.    }     
  10. }  

 對第二個問題修復(fù)的辦法是:

 

Java代碼 
  1. public class Singleton implements java.io.Serializable {     
  2.    public static Singleton INSTANCE = new Singleton();     
  3.       
  4.    protected Singleton() {     
  5.         
  6.    }     
  7.    private Object readResolve() {     
  8.             return INSTANCE;     
  9.       }    
  10. }   
 

對我來說,我比較喜歡第三種和第五種方式,簡單易懂,而且在JVM層實現(xiàn)了線程安全(如果不是多個類加載器環(huán)境),一般的情況下,我會使用第三種方式,只有在要明確實現(xiàn)lazy loading效果時才會使用第五種方式,另外,如果涉及到反序列化創(chuàng)建對象時我會試著使用枚舉的方式來實現(xiàn)單例,不過,我一直會保證我的程序是線程安全的,而且我永遠(yuǎn)不會使用第一種和第二種方式,如果有其他特殊的需求,我可能會使用第七種方式,畢竟,JDK1.5已經(jīng)沒有雙重檢查鎖定的問題了。

========================================================================

 superheizai同學(xué)總結(jié)的很到位:

 

不過一般來說,第一種不算單例,第四種和第三種就是一種,如果算的話,第五種也可以分開寫了。所以說,一般單例都是五種寫法。懶漢,惡漢,雙重校驗鎖,枚舉和靜態(tài)內(nèi)部類。

我很高興有這樣的讀者,一起共勉。

posted on 2010-12-17 03:25 逛奔的蝸牛 閱讀(3148) 評論(0)  編輯 收藏 引用 所屬分類: Java
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲欧美日韩天堂一区二区| 蜜臀99久久精品久久久久久软件 | 国产午夜精品一区二区三区视频| 六月婷婷久久| 欧美国产欧美亚洲国产日韩mv天天看完整 | 蜜臀av在线播放一区二区三区| 久久久久久免费| 性刺激综合网| 一区二区三区自拍| 欧美午夜大胆人体| 亚洲精品日日夜夜| 亚洲视频每日更新| 一本色道久久加勒比精品 | 欧美一区二区免费视频| 在线观看福利一区| 一区二区三区四区蜜桃| 欧美激情中文不卡| 亚洲欧洲另类国产综合| 欧美成人激情在线| 欧美多人爱爱视频网站| 欧美日韩午夜激情| 欧美一区二区三区在线看 | 夜夜夜久久久| 中文av字幕一区| 亚洲区一区二| 亚洲国产mv| 国产精品久久| 欧美日韩高清一区| 国产精品每日更新| 欧美福利网址| 久久在线视频在线| 久久se精品一区精品二区| 欧美一区二区三区四区高清| 一区二区精品国产| 久久亚洲一区二区三区四区| 亚洲国产精品v| 久久久久久综合| 欧美国产日韩一区二区三区| 亚洲一区bb| 亚洲黄色在线| 99在线精品视频在线观看| 欧美成ee人免费视频| 欧美护士18xxxxhd| 亚洲理论电影网| 欧美母乳在线| 亚洲第一精品在线| 日韩视频精品在线| 久久久久久香蕉网| 欧美国产欧美亚州国产日韩mv天天看完整| 亚洲三级影院| 亚洲人精品午夜| 蜜臀91精品一区二区三区| 欧美黄污视频| 一区二区久久久久| 亚洲高清久久| 亚洲二区在线视频| 欧美一区二区性| 久久久一区二区三区| 欧美日韩精品在线视频| 久久综合一区二区| 国产一区二区三区在线免费观看 | 在线不卡欧美| 欧美一区国产在线| 欧美日韩精品一区二区| 亚洲免费婷婷| 美女性感视频久久久| 亚洲黄色成人网| 国产精品伊人日日| 欧美va天堂va视频va在线| 欧美日韩视频在线观看一区二区三区| 亚洲一区bb| 国产九九视频一区二区三区| 亚洲欧美激情四射在线日 | 国产视频精品xxxx| 国产精品久久久久久久久| 欧美高清视频一区| 欧美激情a∨在线视频播放| 久久精品国产一区二区三区| 欧美午夜在线一二页| 香蕉久久夜色精品国产使用方法| 99re热精品| 亚洲黄色在线| 亚洲高清不卡在线| 欧美三级在线| 午夜精品久久久久久久蜜桃app| 亚洲欧美www| 亚洲视频999| 亚洲国产清纯| 伊人色综合久久天天| 欧美国产日韩在线观看| 亚洲一级在线观看| 亚洲国产日韩欧美在线99| 另类酷文…触手系列精品集v1小说| 狼人天天伊人久久| 午夜国产精品视频| 久久久噜噜噜久噜久久| 激情视频一区二区| 久久精品青青大伊人av| 亚洲手机视频| 中国av一区| 国产一区二区激情| 欧美成人一区二区在线| 亚洲夜晚福利在线观看| 香蕉久久久久久久av网站| 亚洲第一偷拍| 国产主播一区二区三区| 在线观看的日韩av| 国产欧美一区二区精品性| 久久躁日日躁aaaaxxxx| 亚洲精品国久久99热| 久久精品1区| 日韩天堂av| 久久久久青草大香线综合精品| 国产精品视频xxxx| 欧美小视频在线| 欧美日韩精品一区二区三区| 国产亚洲欧洲997久久综合| 国产一区在线免费观看| 亚洲福利视频二区| 亚洲少妇在线| 亚洲精品视频在线| 亚洲精品国精品久久99热| 亚洲男女自偷自拍| 日韩亚洲精品在线| 性久久久久久久久久久久| 国产欧美精品xxxx另类| 久久综合999| 欧美一区二区日韩| 亚洲欧美激情四射在线日| 亚洲一区二区黄| 欧美精品久久久久久久| 亚洲午夜国产一区99re久久| 亚洲福利专区| 欧美国产视频在线观看| 99精品国产福利在线观看免费| 亚洲性图久久| 国产欧美日韩精品一区| 欧美中文字幕久久| 快射av在线播放一区| 欧美一区二区三区免费观看| 亚洲片区在线| 久久久久久久999精品视频| 亚洲区一区二| 久久婷婷丁香| 亚洲午夜在线观看| 欧美一区二区成人6969| 麻豆精品网站| 亚洲午夜精品网| 国产精品mm| 欧美夜福利tv在线| 亚洲色图综合久久| 国产亚洲午夜| 狠狠88综合久久久久综合网| 亚洲综合色激情五月| 亚洲高清免费在线| 免费日韩成人| 一级日韩一区在线观看| 亚洲欧美日韩精品久久亚洲区| 欧美高清在线一区二区| 亚洲理论在线观看| 久久免费高清视频| 亚洲欧洲一区二区在线播放| 亚洲欧美精品中文字幕在线| 国产日韩亚洲欧美综合| 亚洲高清av| 激情伊人五月天久久综合| 99re8这里有精品热视频免费| aaa亚洲精品一二三区| 欧美精品首页| 久久国产精品72免费观看| 亚洲欧美日韩高清| 久久久999精品| 欧美—级在线免费片| 国产午夜精品一区理论片飘花 | 亚洲高清不卡| 亚洲第一免费播放区| 欧美精品久久一区二区| 欧美一区日本一区韩国一区| 久久精品在线免费观看| 农村妇女精品| 国产精品久久久久久模特| 日韩一二三区视频| 国产精品女主播一区二区三区| 欧美激情中文字幕乱码免费| 亚洲永久免费av| 欧美刺激午夜性久久久久久久| 欧美h视频在线| 韩国欧美国产1区| 在线午夜精品| 亚洲欧美99| 欧美在线视频导航| 在线视频一区二区| 久久免费视频这里只有精品| 国产麻豆一精品一av一免费| 亚洲免费在线电影| 影视先锋久久| 欧美电影免费观看网站| 免播放器亚洲| 免费在线欧美黄色| 久久精品视频播放|