一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

《Head First設(shè)計(jì)模式》閱讀筆記.第五章

 昵稱(chēng)465563 2010-10-27
1.單件(單態(tài),Singleton)模式部分

*有些對(duì)象我們只需要一個(gè),比如說(shuō):線程池(threadpool)、緩存(cache)、對(duì)話框()、處理偏好設(shè)置的對(duì)象、處理注冊(cè)表(register)的對(duì)象、日志對(duì)象,以及充當(dāng)打印機(jī)、顯卡等設(shè)備的驅(qū)動(dòng)程序?qū)ο蟆_@些對(duì)象只能有一個(gè)實(shí)例,如果出現(xiàn)多個(gè)實(shí)例就會(huì)導(dǎo)致程序的行為異常、資源使用過(guò)量,或者產(chǎn)生的結(jié)果不一致等等問(wèn)題。

*單件模式與全局靜態(tài)變量的區(qū)別:
(1)使用全局靜態(tài)變量需要程序員之間的約定才能保證只有一個(gè)實(shí)例,而單件模式無(wú)需這樣的約定就可以確保只有一個(gè)實(shí)例被創(chuàng)建。
(2)靜態(tài)變量在程序一開(kāi)始就被創(chuàng)建(這取決于JVM的實(shí)現(xiàn)),而單件模式只是在使用時(shí)才創(chuàng)建對(duì)象。如果這個(gè)被創(chuàng)建的對(duì)象非常消耗資源,而在程序運(yùn)行的過(guò)程中沒(méi)有用到它,就會(huì)造成很大的浪費(fèi),這是靜態(tài)變量的缺點(diǎn)。

*在單態(tài)模式中,如果不需要這個(gè)實(shí)例,它就永遠(yuǎn)不會(huì)被創(chuàng)建。這就是“延遲實(shí)例化(Lazy Instance)”。

*單件模式的應(yīng)用場(chǎng)景之一是設(shè)置類(lèi)對(duì)象,比如注冊(cè)表設(shè)置(Register Setting)對(duì)象。如果設(shè)置對(duì)象有多份拷貝,就會(huì)把設(shè)置搞得一團(tuán)糟。

*單件常用來(lái)管理共享的資源,比如數(shù)據(jù)庫(kù)連接池或線程池。

單件(Singleton)模式:確保一個(gè)類(lèi)只有一個(gè)實(shí)例,并提供一個(gè)全局訪問(wèn)點(diǎn)。

*多線程會(huì)影響到單件模式,如果不對(duì)它進(jìn)行處理就會(huì)在單件模式下仍然創(chuàng)建多于一個(gè)實(shí)例。
解決這個(gè)問(wèn)題有以下三種方式:
(1)使用同步。但是簡(jiǎn)單地給創(chuàng)建實(shí)例方法(getInstance())增加synchronized修飾符雖然可以解決多線程的問(wèn)題,但是導(dǎo)致每次調(diào)用都同步,而在靜態(tài)變量被設(shè)置之后,同步就是多余的了,因此,這降低了程序的效率。
在程序頻繁運(yùn)行的地方增加同步可能會(huì)使效率降低100倍!因此要盡量避免使用同步,如果使用,就要盡量縮減需要同步的代碼。
方法如下:
Java代碼 復(fù)制代碼
  1. ------------   
  2. public class Singleton {   
  3.     private static Singleton instance;   
  4.        
  5.     private Singleton() {}   
  6.        
  7.     public synchronized static Singleton getInstance() {   
  8.         if (instance == null) {   
  9.             instance = new Singleton();   
  10.         }   
  11.         return instance;   
  12.     }   
  13. }   
  14. ------------  

(2)使用“急切(eagerly)”創(chuàng)建實(shí)例,也就是在生命靜態(tài)變量的時(shí)候就創(chuàng)建實(shí)例,而不是等到使用的時(shí)候再創(chuàng)建。該方式適用于程序總是需要?jiǎng)?chuàng)建和使用單件實(shí)例、程序在創(chuàng)建和運(yùn)行時(shí)負(fù)擔(dān)不是太重、單件實(shí)例占用的資源較少的情況。
方法如下:
Java代碼 復(fù)制代碼
  1. ------------   
  2. public class Singleton {   
  3.     private static Singleton instance = new Singleton();   
  4.        
  5.     private Singleton() {}   
  6.        
  7.     public static Singleton getInstance() {   
  8.         return instance;   
  9.     }   
  10. }   
  11. ------------  

(3)在創(chuàng)建實(shí)例方法(getInstance())方法中使用“雙重檢查加鎖(Double-Checked Locking)”,這樣既保持了“延遲實(shí)例化(Lazy Instance)”,又保證只在第一次調(diào)用時(shí)同步。
方法如下:
Java代碼 復(fù)制代碼
  1. ------------   
  2. public class Singleton {   
  3.     private volatile static Singleton instance;   
  4.        
  5.     private Singleton() {}   
  6.        
  7.     public static Singleton getInstance() {   
  8.         if (instance == null) {   
  9.             synchronized (Singleton.class) {   
  10.                 if (instance == null) {   
  11.                     instance = new Singleton();   
  12.                 }   
  13.             }   
  14.         }   
  15.         return instance;   
  16.     }   
  17. }   
  18. ------------  

在這個(gè)方法里使用到了volatile這個(gè)關(guān)鍵字,下面對(duì)這個(gè)“關(guān)鍵的”關(guān)鍵字進(jìn)行說(shuō)明:
Java語(yǔ)言規(guī)范指出,為了獲得最佳速度,允許線程保存共享成員變量的私有拷貝,而且只當(dāng)線程進(jìn)入和離開(kāi)同步代碼塊時(shí)才與共享成員變量的原始值進(jìn)行對(duì)比。
而被volatile修飾的成員變量在線程中的私有拷貝每次被線程訪問(wèn)時(shí),都強(qiáng)迫從共享內(nèi)存中重讀該成員變量的值。而且,當(dāng)成員變量的私有拷貝發(fā)生變化時(shí),強(qiáng)迫線程將變化值回寫(xiě)到共享內(nèi)存。這樣在任何時(shí)刻,兩個(gè)不同的線程總是看到某個(gè)成員變量的同一個(gè)值。
因此volatile關(guān)鍵字是使“雙重檢查加鎖(Double-Checked Locking)”有效的前提。
但是需要注意,在1.4及以前版本的JDK中,JVM對(duì)volatile關(guān)鍵字的實(shí)現(xiàn)會(huì)導(dǎo)致雙重檢查加鎖失效,所以這個(gè)方法只適用于1.5(包含)以后版本。

*以上對(duì)三種處理多線程方法的總結(jié)也就是“Sharpen Your Pencil”的解答。

*可以通過(guò)把一個(gè)類(lèi)中的全部方法都定義為靜態(tài)方法的方式來(lái)達(dá)到和單件模式同樣的效果,但是由于類(lèi)的初始化順序由JVM控制,所以可能導(dǎo)致與初始化順序有關(guān)的BUG,而這樣的BUG常常難于被發(fā)現(xiàn)。當(dāng)類(lèi)的初始化比較簡(jiǎn)單時(shí),可以使用此方法。

*類(lèi)加載器會(huì)破壞單件模式,因?yàn)椴煌念?lèi)加載器可以分別創(chuàng)建同一個(gè)單件的對(duì)象,單件對(duì)象就有了多個(gè)實(shí)例。解決辦法是:自行指定類(lèi)加載器,并且指定同一個(gè)類(lèi)加載器。

*在Java 1.2及以前版本中,垃圾收集器有一個(gè)BUG,會(huì)造成單件在沒(méi)有全局引用時(shí),被當(dāng)做垃圾清理掉。在1.2以后的版本中,這個(gè)BUG已經(jīng)得到了修復(fù),因此不用擔(dān)心了。
如果使用的是1.2及以前的版本,可以建立一個(gè)單件注冊(cè)表(Register),從而避免單件被垃圾收集器回收。

*雖然單件模式不支持繼承,但在一個(gè)軟件中用到它的機(jī)會(huì)并不多,所以這個(gè)限制幾乎沒(méi)有影響。

*Java中實(shí)現(xiàn)單件(Singleton)模式需要私有的構(gòu)造器、一個(gè)靜態(tài)變量和一個(gè)靜態(tài)方法。

2.單件(Singleton)模式實(shí)例

第一種實(shí)現(xiàn):
Java代碼 復(fù)制代碼
  1. public class ThreadPool {   
  2.     private static ThreadPool instance;   
  3.   
  4.     private ThreadPool() {   
  5.     }   
  6.   
  7.     public synchronized static ThreadPool getInstance() {   
  8.         if (instance == null) {   
  9.             instance = new ThreadPool();   
  10.         }   
  11.         return instance;   
  12.     }   
  13. }  


第二種實(shí)現(xiàn):
Java代碼 復(fù)制代碼
  1. public class DBConnectionPool {   
  2.     private static DBConnectionPool instance = new DBConnectionPool();   
  3.   
  4.     private DBConnectionPool() {   
  5.     }   
  6.   
  7.     public static DBConnectionPool getInstance() {   
  8.         return instance;   
  9.     }   
  10. }  


第三種實(shí)現(xiàn)(適用于1.5及以后版本):
Java代碼 復(fù)制代碼
  1. public class LogFactory {   
  2.     private volatile static LogFactory instance;   
  3.   
  4.     private LogFactory() {   
  5.     }   
  6.   
  7.     public static LogFactory getInstance() {   
  8.         if (instance == null) {   
  9.             synchronized (LogFactory.class) {   
  10.                 if (instance == null) {   
  11.                     instance = new LogFactory();   
  12.                 }   
  13.             }   
  14.         }   
  15.         return instance;   
  16.     }   
  17. }  


--END--

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多

    日韩一区二区三区四区乱码视频| 国产一区二区三区香蕉av| 欧美亚洲国产日韩一区二区| 欧美日韩最近中国黄片| 中国黄色色片色哟哟哟哟哟哟| 久久人妻人人澡人人妻| 亚洲综合激情另类专区老铁性| 手机在线观看亚洲中文字幕| 日本高清视频在线播放| 91午夜少妇极品福利| 中日韩美女黄色一级片| 欧美精品在线播放一区二区| 亚洲精品福利视频你懂的| 国产精品视频第一第二区| 国产精品免费视频视频| 91亚洲精品国产一区| 国产精品免费视频久久| 婷婷激情四射在线观看视频| 国产又猛又黄又粗又爽无遮挡| 午夜视频在线观看日韩| 欧美国产日本免费不卡| 成人午夜激情免费在线| 亚洲一区二区三区熟女少妇| 日本高清视频在线播放| 亚洲欧美国产中文色妇| 日韩人妻免费视频一专区| 欧美又黑又粗大又硬又爽| 蜜臀人妻一区二区三区| 女人高潮被爽到呻吟在线观看| 欧美精品一区二区水蜜桃| 一二区中文字幕在线观看| 九九热这里只有免费精品| 激情五月激情婷婷丁香| 男女午夜福利院在线观看| 中日韩免费一区二区三区| 国产一区欧美一区二区| 国产熟女一区二区三区四区| 国产又大又硬又粗又黄| 在线免费视频你懂的观看| 国产又粗又黄又爽又硬的| 午夜福利视频偷拍91|