精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

漫談設計模式-技術要點詳解

開發 后端
本篇文章給出其中的一章供參考,想閱讀書籍全部內容,請參見原文附件, 示例代碼也在附件里,也可以登錄http://code.google.com/p/rambling-on-patterns/下載代碼。

第3章 單例(Singleton)模式

3.1 概述

如果要保證系統里一個類最多只能存在一個實例時,我們就需要單例模式。這種情況在我們應用中經常碰到,例如緩存池,數據庫連接池,線程池,一些應用服務實例等。在多線程環境中,為了保證實例的唯一性其實并不簡單,這章將和讀者一起探討如何實現單例模式。

3.2 最簡單的單例

為了限制該類的對象被隨意地創建,我們保證該類構造方法是私有的,這樣外部類就無法創建該類型的對象了;另外,為了給客戶對象提供對此單例對象的使用,我們為它提供一個全局訪問點,代碼如下所示:

 

  1. public class Singleton {   
  2.     private static Singleton instance = new Singleton();     
  3.     //other fields…   
  4.  
  5.     private Singleton() {   
  6.     }   
  7.  
  8.     public static Singleton getInstance() {   
  9.         return instance;   
  10.     }   
  11.      
  12.     //other methods…   
  13. }   

 

代碼注解:

l Singleton類的只有一個構造方法,它是被private修飾的,客戶對象無法創建該類實例。

l 我們為此單例實現的全局訪問點是public static Singleton getInstance()方法,注意,instance變量是私有的,外界無法訪問的。

讀者還可以定義instance變量是public的,這樣把屬性直接暴露給其他對象,就沒必要實現public static Singleton getInstance()方法,但是可讀性沒有方法來的直接,而且把該實例變量的名字直接暴露給客戶程序,增加了代碼的耦合度,如果改變此變量名稱,會引起客戶類的改變。

還有一點,如果該實例需要比較復雜的初始化過程時,把這個過程應該寫在static{…}代碼塊中。

l 此實現是線程安全的,當多個線程同時去訪問該類的getInstance()方法時,不會初始化多個不同的對象,這是因為,JVM(Java Virtual Machine)在加載此類時,對于static屬性的初始化只能由一個線程執行且僅一次[1]。

由于此單例提供了靜態的公有方法,那么客戶使用單例模式的代碼也就非常簡單了,如下所示:

Singleton singleton = Singleton.getInstance();

3.3 進階

3.3.1 延遲創建

如果出于性能等的考慮,我們希望延遲實例化單例對象(Static屬性在加載類是就會被初始化),只有在第一次使用該類的實例時才去實例化,我們應該怎么辦呢?

這個其實并不難做到,我們把單例的實例化過程移至getInstance()方法,而不在加載類時預先創建。當訪問此方法時,首先判斷該實例是不是已經被實例化過了,如果已被初始化,則直接返回這個對象的引用;否則,創建這個實例并初始化,最后返回這個對象引用。代碼片段如下所示:

 

  1. public class UnThreadSafeSingelton {   
  2.     //variables and constructors…   
  3.  
  4.     public static UnThreadSafeSingelton getInstance() {   
  5.         if(instatnce ==null){   
  6.           instatnce = new UnThreadSafeSingelton();   
  7.         }   
  8.         return instatnce;   
  9.     }   
  10. }   

 

我們使用這句if(instatnce ==null) 判斷是否實例化完成了。此方法不是線程安全的,接下來我們將會討論。

3.3.2 線程安全

上節我們創建了可延遲初始化的單例,然而不幸的是,在高并發的環境中,getInstance()方法返回了多個指向不同的該類實例,究竟是什么原因呢?我們針對此方法,給出兩個線程并發訪問getInstance()方法時的一種情況,如下所示:

t1 t2

1 if(instatnce ==null)

2 if(instatnce ==null)

3 instatnce = new UnThreadSafeSingelton();

4 return instatnce;

5 instatnce = new UnThreadSafeSingelton()

6 return instatnce;

如果這兩個線程按照上述步驟執行,不難發現,在時刻1和2,由于還沒有創建單例對象,Thread1和Thread2都會進入創建單例實例的代碼塊分別創建實例。在時刻3,Thread1創建了一個實例對象,但是Thread2此時已無法知道,繼續創建一個新的實例對象,于是這兩個線程持有的實例并非為同一個。更為糟糕的是,在沒有自動內存回收機制的語言平臺上運行這樣的單例模式,例如使用C++編寫此模式,因為我們認為創建了一個單例實例,忽略了其他線程所產生的對象,不會手動去回收它們,引起了內存泄露。

為了解決這個問題,我們給此方法添加synchronized關鍵字,代碼如下:

 

  1. public class ThreadSafeSingelton {   
  2.     //variables and constructors…   
  3.  
  4.     public static synchronized ThreadSafeSingelton getInstance() {   
  5.         if(instatnce ==null){   
  6.             instatnce = new ThreadSafeSingelton();   
  7.         }   
  8.         return instatnce;   
  9.     }   
  10. }   

 

這樣,再多的線程訪問都只會實例化一個單例對象。

3.3.3 Double-Check Locking

上述途徑雖然實現了多線程的安全訪問,但是在多線程高并發訪問的情況下,給此方法加上synchronized關鍵字會使得性能大不如前。我們仔細分析一下不難發現,使用了synchronized關鍵字對整個getInstance()方法進行同步是沒有必要的:我們只要保證實例化這個對象的那段邏輯被一個線程執行就可以了,而返回引用的那段代碼是沒有必要同步的。按照這個想法,我們的代碼片段大致如下所示:

 

  1. public class DoubleCheckSingleton {   
  2.     private volatile static DoubleCheckSingleton instatnce = null;   
  3.  
  4.     //constructors   
  5.  
  6.     public static DoubleCheckSingleton getInstance() {   
  7.         if (instatnce == null) {   //check if it is created.   
  8.             synchronized (DoubleCheckSingleton.class) {  //synchronize creation block   
  9.                 if (instatnce == null)   //double check if it is created   
  10.                     instatnce = new DoubleCheckSingleton();   
  11.             }   
  12.         }   
  13.         return instatnce;   
  14.     }   
  15. }   

 

代碼注解:

l 在getInstance()方法里,我們首先判斷此實例是否已經被創建了,如果還沒有創建,首先使用synchronized同步實例化代碼塊。在同步代碼塊里,我們還需要再次檢查是否已經創建了此類的實例,這是因為:如果沒有第二次檢查,這時有兩個線程Thread A和Thread B同時進入該方法,它們都檢測到instatnce為null,不管哪一個線程先占據同步鎖創建實例對象,都不會阻止另外一個線程繼續進入實例化代碼塊重新創建實例對象,這樣,同樣會生成兩個實例對象。所以,我們在同步的代碼塊里,進行第二次判斷判斷該對象是否已被創建。

正是由于使用了兩次的檢查,我們稱之為double-checked locking模式。

l 屬性instatnce是被volatile修飾的,因為volatile具有synchronized的可見性特點,也就是說線程能夠自動發現volatile變量的最新值。這樣,如果instatnce實例化成功,其他線程便能立即發現。

注意:

此程序只有在JAVA 5及以上版本才能正常運行,在以前版本不能保證其正常運行。這是由于Java平臺的內存模式容許out-of-order writes引起的,假定有兩個線程,Thread 1和Thread 2,它們執行以下步驟:

1. Thread 1發現instatnce沒有被實例化,它獲得鎖并去實例化此對象,JVM容許在沒有完全實例化完成時,instance變量就指向此實例,因為這些步驟可以是out-of-order writes的,此時instance==null為false,之前的版本即使用volatile關鍵字修飾也無效。

2. 在初始化完成之前,Thread 2進入此方法,發現instance已經不為null了,Thread 2便認為該實例初始化完成了,使用這個未完全初始化的實例對象,則很可能引起系統的崩潰。

3.3.4 Initialization on demand holder

要使用線程安全的延遲的單例初始化,我們還有一種方法,稱為Initialization on demand holder模式,代碼如下所示:

 

  1. public class LazyLoadedSingleton {   
  2.     private LazyLoadedSingleton() {   
  3.        }   
  4.  
  5.        private static class LazyHolder {  //holds the singleton class   
  6.               private static final LazyLoadedSingleton singletonInstatnce = new LazyLoadedSingleton();   
  7.        }   
  8.  
  9.        public static LazyLoadedSingleton getInstance() {   
  10.               return LazyHolder.singletonInstatnce;   
  11.        }   
  12. }   

 

當JVM加載LazyLoadedSingleton類時,由于該類沒有static屬性,所以加載完成后便即可返回。只有第一次調用getInstance()方法時,JVM才會加載LazyHolder類,由于它包含一個static屬性singletonInstatnce,所以會首先初始化這個變量,根據前面的介紹,我們知道此過程并不會出現并發問題(JLS保證),這樣即實現了一個既線程安全又支持延遲加載的單例模式。

3.3.5 Singleton的序列化

如果單例類實現了Serializable接口,這時我們得特別注意,因為我們知道在默認情況下,每次反序列化(Desierialization)總會創建一個新的實例對象,這樣一個系統會出現多個對象供使用。我們應該怎么辦呢?

熟悉Java序列化的讀者可能知道,我們需要在readResolve()方法里做文章,此方法在反序列化完成之前被執行,我們在此方法里替換掉反序列化出來的那個新的實例,讓其指向內存中的那個單例對象即可,代碼實現如下:

 

  1. import java.io.Serializable;   
  2.  
  3. public class SerialibleSingleton implements Serializable {   
  4.     private static final long serialVersionUID = -6099617126325157499L;   
  5.     static SerialibleSingleton singleton = new SerialibleSingleton();   
  6.  
  7.     private SerialibleSingleton() {   
  8.     }   
  9.  
  10.     // This method is called immediately after an object of this class is deserialized.   
  11.     // This method returns the singleton instance.   
  12.     private Object readResolve() {   
  13.         return singleton;   
  14.     }   
  15. }   

 

方法readResolve()直接返回singleton單例,這樣,我們在內存中始終保持了一個唯一的單例對象。

3.4 總結

通過這一章的學習,我相信大家對于基本的單例模式已經有了一個比較充分的認識。其實我們這章討論的是在同一個JVM中,如何保證一個類只有一個單例,如果在分布式環境中,我們可能需要考慮如何保證在整個應用(可能分布在不同JVM上)只有一個實例,但這也超出本書范疇,在這里將不再做深入研究,有興趣的讀者可以查閱相關資料深入研究。

________________________________________

[1] Static屬性和Static初始化塊(Static Initializers)的初始化過程是串行的,這個由JLS(Java Language Specification)保證,參見James Gosling, Bill Joy, Guy Steele and Gilad Bracha編寫的《 The Java™ Language Specification Third Edition》一書的12.4一節。

原文鏈接:http://redhat.iteye.com/blog/1007884

責任編輯:金賀 來源: ITEYE博客
相關推薦

2010-03-25 08:52:30

PHP設計模式代理模式

2010-04-19 09:30:00

工廠模式PHP設計模式

2010-04-13 08:54:28

PHP設計模式命令模式

2010-04-08 09:27:04

PHP設計模式結構模式

2010-04-21 08:38:18

解釋器模式PHP設計模式

2010-07-08 14:25:12

HART協議

2010-04-01 09:10:03

PHP設計模式責任鏈模式

2010-04-29 08:53:11

PHP迭代器模式

2010-05-06 08:44:37

調解者模式

2011-06-02 18:02:50

iPhone MVC

2009-11-11 17:48:36

OSPF路由技術

2009-10-15 13:11:28

綜合布線系統

2021-06-29 08:54:23

設計模式代理模式遠程代理

2009-08-18 11:03:31

Observer設計模

2018-02-07 15:25:41

2015-09-15 09:20:22

Neutron技術虛擬化

2011-07-26 15:29:36

Cocoa 模式

2011-07-26 17:31:52

iOS 設計模式

2009-07-10 16:14:29

MVC設計模式Swing

2009-06-25 14:32:00

Java BS開發模式
點贊
收藏

51CTO技術棧公眾號

在线成人免费| 国产裸舞福利在线视频合集| 亚洲自拍偷拍网| 欧美精品一区男女天堂| 欧美视频第一区| 麻豆影视在线观看_| 成人网页在线观看| 国产精品视频一| 久久久精品视频免费| 欧美系列电影免费观看| 精品欧美一区二区在线观看| 亚洲 中文字幕 日韩 无码| 91精品久久久久久粉嫩| 久久精品一区蜜桃臀影院| 成人免费福利在线| 依依成人综合网| 成人免费电影网址| 亚洲第一天堂av| 国产三级国产精品国产专区50| 美女精品导航| 18欧美亚洲精品| 日韩videos| 天堂av资源网| 国产一区二区不卡老阿姨| 日韩av高清不卡| 精品成人免费视频| 一区二区三区毛片免费| 在线观看精品自拍私拍| 97人妻天天摸天天爽天天| 亚洲专区**| 欧美日韩成人综合在线一区二区 | 久久久久亚洲AV成人网人人小说| 福利一区二区| 日本久久一区二区| 5月婷婷6月丁香| 国产天堂在线播放视频| 亚洲色图都市小说| 亚洲一区3d动漫同人无遮挡 | 国产亚洲精彩久久| 亚洲成人中文在线| 黄黄视频在线观看| 看黄网站在线观看| 国产精品午夜在线观看| caoporn成人| 1024精品合集| 一区二区三视频| 成人在线二区| 日韩在线一卡二卡| 伊伊综合在线| 婷婷激情综合网| 黄色三级中文字幕| av网站大全在线| 亚洲欧美日本在线| 好色先生视频污| 精品自拍一区| 中文字幕中文字幕一区| 午夜精品视频在线观看一区二区| 牛牛热在线视频| 91在线小视频| 蜜桃传媒视频麻豆一区 | 亚洲欧美精品在线| 熟女少妇一区二区三区| 国产一区网站| 中文字幕日韩免费视频| 俄罗斯毛片基地| 欧美a级成人淫片免费看| www.日韩不卡电影av| 国产精品嫩草影院俄罗斯| 天堂美国久久| 欧美激情xxxx性bbbb| 久久久国产精华液| 一本色道久久综合亚洲精品高清 | 91在线观看高清| 日本一区二区三区精品视频| a天堂在线资源| 自拍偷拍欧美精品| av女优在线播放| 男人天堂视频网| 久久午夜电影| 国产精品丝袜视频| 国产精品久久久久久久免费| 国产精品996| 国产伦精品一区二区三区照片91 | 一级黄色av片| 精品一区免费av| y111111国产精品久久婷婷| 天堂av2024| 国产精品久久午夜| 黄色激情在线视频| 不卡一二三区| 欧美一区二区日韩| 欧美 日本 国产| 99精品在线观看| 91精品国产自产91精品| 真实新婚偷拍xxxxx| 国产成人精品一区二| 精品一区二区久久久久久久网站| 国产片在线观看| 一区二区三区日韩在线观看| 免费无码av片在线观看| 欧美中文高清| 亚洲免费电影在线观看| 久热这里有精品| 日韩精品一二区| 97se国产在线视频| 成年人视频免费在线观看| 亚洲福利一区二区| 久久久精品高清| 亚洲免费专区| 欧美极品少妇xxxxⅹ裸体艺术| 波多野结衣视频网址| 成人h动漫精品| 爱爱爱视频网站| 日本综合字幕| 亚洲电影免费观看高清完整版在线观看| 粉嫩精品久久99综合一区| 夜久久久久久| 国产精品久久久久久久久婷婷| 色老头视频在线观看| 亚洲18色成人| 性生交大片免费看l| 国产91丝袜在线播放0| 亚洲乱码一区av黑人高潮| 正在播放国产对白害羞| 午夜亚洲福利| 91精品国产99久久久久久| 91久久精品无码一区二区| 91麻豆国产在线观看| 久久国产精品免费观看| 成人在线免费av| 日韩一区二区三区视频在线观看 | av国产精品| 日韩电影中文字幕在线| 黄色一级片中国| 免费一级片91| 欧美日产一区二区三区在线观看| 777电影在线观看| 在线观看视频欧美| 三级男人添奶爽爽爽视频| 91成人精品| 国产精品入口日韩视频大尺度| 午夜小视频免费| 亚洲蜜臀av乱码久久精品蜜桃| 在线能看的av网站| 国产va免费精品观看精品视频| 久久久伊人日本| 亚洲国产成人一区二区| 玉米视频成人免费看| 手机在线成人免费视频| 国产亚洲一卡2卡3卡4卡新区 | 亚洲av片不卡无码久久| 午夜亚洲福利| 国产一区二区三区高清视频| 超碰电影在线播放| 777亚洲妇女| 麻豆一区在线观看| 麻豆久久久久久久| 一区二区三区四区五区精品| 亚洲成人人体| 亚洲欧美日韩成人| 无码人妻av一区二区三区波多野| 91麻豆福利精品推荐| 国产h视频在线播放| 亚洲电影一级片| 人九九综合九九宗合| 日本一本草久在线中文| 日本乱人伦一区| 免费福利视频网站| 国产精品白丝喷水在线观看| 国产日韩1区| 国产伦一区二区三区色一情| av福利导福航大全在线| 日韩精品一区二区三区中文不卡| 久久精品99久久久久久| 成人三级伦理片| 国产va亚洲va在线va| 美国成人xxx| 日韩av电影中文字幕| 黄色网页在线免费观看| 欧美成人乱码一区二区三区| 国产午夜久久久| 久久在线观看免费| 久草福利视频在线| 欧美激情成人| 久久99精品久久久久久久青青日本 | 免费观看日韩av| 一区二区三区的久久的视频| 国产精品一区免费在线| 韩剧1988免费观看全集| 色噜噜一区二区三区| 日本韩国视频一区二区| 国产美女永久免费无遮挡| 精品亚洲成av人在线观看| www.日本三级| 欧美综合视频| y111111国产精品久久婷婷| 日韩精品三区| 久热精品视频在线观看| 亚洲欧洲精品视频| 欧美日韩一区二区三区四区| 免费无码毛片一区二区app| 成人一级片网址| 超碰在线公开97| 亚洲承认在线| 深田咏美在线x99av| 欧州一区二区三区| 国产精品av免费在线观看| 爱情岛亚洲播放路线| 国产亚洲视频在线观看| 亚洲国产成人精品一区二区三区| 在线看国产一区| 精品一区在线视频| 一区二区三区产品免费精品久久75| 午夜一区二区三区免费| 国产美女一区二区| 日韩av播放器| 黄色成人精品网站| 亚洲精品国产精品国自产| 国产精品qvod| 成人免费视频网址| 性欧美gay| 97精品国产97久久久久久| 亚洲av片一区二区三区| 精品国产精品一区二区夜夜嗨| 在线观看亚洲一区二区| 欧美日韩性视频| 久久艹精品视频| 国产网站一区二区三区| 亚洲色图14p| 成人午夜激情视频| 精品人妻一区二区三区免费| 奇米影视在线99精品| 福利视频一区二区三区四区| 欧美国产高清| 宅男av一区二区三区| 精品九九在线| 欧美12av| 777久久精品| 不卡视频一区二区三区| 日韩伦理一区二区| 国产精品欧美在线| 台湾佬中文娱乐久久久| 97久久精品在线| 牛牛精品在线视频| 欧美老少配视频| 久cao在线| 久久精品视频va| 国产在线激情| 久久高清视频免费| 免费在线视频欧美| 久久精品国产久精国产一老狼| 亚洲三区在线播放| 亚洲另类欧美自拍| 色哟哟在线观看| 亚洲国内高清视频| 熟妇人妻av无码一区二区三区| 亚洲黄在线观看| 色欲av永久无码精品无码蜜桃| 欧美变态tickle挠乳网站| 国产情侣在线播放| 欧美精品一级二级| 蜜桃久久一区二区三区| 亚洲国产高清福利视频| 天堂网av2014| 日韩精品在线视频| 2017亚洲天堂1024| www.欧美精品| 99久久精品免费观看国产| 久久99精品久久久久久琪琪| 老司机福利在线视频| 久久久久一本一区二区青青蜜月| av女在线播放| 日韩美女写真福利在线观看| 在线观看精品| 91视频免费网站| 伊人久久影院| 精品免费二区三区三区高中清不卡| 噜噜噜狠狠夜夜躁精品仙踪林| 免费av一区二区三区| 天天久久综合| 三上悠亚久久精品| 日韩专区欧美专区| www.五月天色| 久久综合国产精品| 亚洲AV成人无码网站天堂久久| 亚洲免费观看高清完整版在线观看熊 | 精品在线99| 午夜精品区一区二区三 | www.中文字幕在线| 日本三级亚洲精品| 久久精品无码一区二区三区毛片| 成人福利电影精品一区二区在线观看| 在线观看日韩精品视频| 成人免费在线播放视频| 国产无码精品在线观看| 欧洲一区二区三区在线| av中文字幕观看| 亚洲人成自拍网站| av毛片在线播放| 2019中文字幕在线免费观看| 国产毛片精品久久| 国产精品美女xx| 正在播放日韩欧美一页| 91好吊色国产欧美日韩在线| 久久电影国产免费久久电影| 日本在线视频播放| 国产日韩精品一区二区浪潮av| 少妇影院在线观看| 色94色欧美sute亚洲线路一久| 国产xxxx孕妇| 亚洲免费人成在线视频观看| 色网在线观看| 国产精品吴梦梦| 日韩美女毛片| 日本大胆人体视频| 日韩精品电影在线| 久草福利在线观看| 91色porny蝌蚪| 激情五月色婷婷| 日韩区在线观看| h视频网站在线观看| 性欧美激情精品| ccyy激情综合| 欧美a级黄色大片| 天堂蜜桃一区二区三区| av在线天堂网| 中文字幕一区二| 青青艹在线观看| 日韩精品在线免费观看| 91www在线| 91在线观看网站| 婷婷色综合网| 中文字幕av不卡在线| 国产三级精品在线| 99re国产在线| 日韩精品高清在线观看| 香蕉视频免费在线播放| 国产在线观看一区二区三区 | 777午夜精品免费视频| www亚洲人| 午夜精品蜜臀一区二区三区免费| 国产精品xxxav免费视频| 亚洲色图都市激情| 韩日欧美一区二区三区| 中文字幕伦理片| 欧美日韩综合色| av免费观看一区二区| 情事1991在线| 精品一区av| 中文字幕视频在线免费观看| 久久久精品tv| 999视频在线| 主播福利视频一区| 日韩成人综合网站| 一区二区三区在线观看www| 捆绑调教一区二区三区| 中文字幕在线观看2018| 88在线观看91蜜桃国自产| 精品51国产黑色丝袜高跟鞋| 91精品久久久久久久久不口人| 911精品美国片911久久久| 色婷婷综合在线观看| 亚洲免费观看视频| 国产精品女人久久久| 久久久久久久激情视频| 国产福利资源一区| 欧美一级欧美一级| av在线不卡电影| 国产视频1区2区| 国产亚洲欧洲高清| 少妇高潮一区二区三区99| 肉大捧一出免费观看网站在线播放| 国产99一区视频免费| 男女视频免费看| 亚洲第一福利网站| 日本欧美韩国| 国产精品久久成人免费观看| 懂色av一区二区三区免费观看| 国产成人无码精品久久久久| 亚洲人成绝费网站色www| a屁视频一区二区三区四区| 先锋影音男人资源| 97精品超碰一区二区三区| 天天干,天天干| 久久久精品网站| 亚洲一区二区免费在线观看| av动漫在线观看| 国产精品久久久久久久久果冻传媒| 国产三级小视频| 日本欧美一级片| 久久电影院7| 欧美做受高潮中文字幕| 在线精品视频一区二区三四| 麻豆tv免费在线观看| 国模精品一区二区三区| 久久久亚洲一区| 国产亚洲精品久久久久久无几年桃| 国产视频精品va久久久久久| 国产原创一区| 欧美激情 国产精品|