




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、1、單例模式單例對象(Singleton )是一種常用的設計模式。在Java應用中,單例對象能保 證在一個JVM中,該對象只有一個實例存在。正是由于這個特點,單例對象通常作為程序中的存放配置信息的載體,因為它能保證其他對象讀到一致的信息。 例如在某個服務器程序中,該服務器的配置信息可能存放在數(shù)據(jù)庫或文件中,這些配置數(shù)據(jù)由某個單例對象統(tǒng)一讀取,服務進程中的其他對象如果要獲取這些 配置信息,只需訪問該單例對象即可。這種方式極大地簡化了在復雜環(huán)境下,尤其是多線程環(huán)境下的配置管理,但是隨著應用場景的不同,也可能帶來一些同 步問題。本文將探討一下在多線程環(huán)境下,使用單例對象作配置信息管理時可能會帶 來的
2、幾個同步問題,并針對每個問題給出可選的解決辦法。問題描述在多線程環(huán)境下,單例對象的同步問題主要體現(xiàn)在兩個方面,單例對象的初始化和單例對象的屬性更新。本文描述的方法有如下假設:1. 單例對象的屬性(或成員變量)的獲取,是通過單例對象的初始化實現(xiàn) 的。也就是說,在單例對象初始化時,會從文件或數(shù)據(jù)庫中讀取最新的配置信息。2. 其他對象不能直接改變單例對象的屬性,單例對象屬性的變化來源于配 置文件或配置數(shù)據(jù)庫數(shù)據(jù)的變化。1.1單例對象的初始化首先,討論一下單例對象的初始化同步。 單例模式的通常處理方式是,在對 象中有一個靜態(tài)成員變量,其類型就是單例類型本身;如果該變量為 null ,則 創(chuàng)建該單例類型
3、的對象,并將該變量指向這個對象;如果該變量不為 null,則 直接使用該變量。其過程如下面代碼所示:public class GlobalC onfig private static GlobalConfig instanee = null;private Vector properties = nu II;private GlobalCo nfig() /Load con figurati on in formatio n from DB or file/Set values for propertiespublic static GlobalC onfig get In sta nce()
4、 if (in sta nee = nu II) in sta nee = new GlobalC on fig();return in sta nee;public Vector getProperties() retur n properties;這種處理方式在單線程的模式下可以很好的運行;但是在多線程模式下,可能產(chǎn) 生問題。如果第一個線程發(fā)現(xiàn)成員變量為 null ,準備創(chuàng)建對象;這是第二 個線 程同時也發(fā)現(xiàn)成員變量為null,也會創(chuàng)建新對象。這就會造成在一個 JVM中有 多個單例類型的實例。如果這個單例類型的成員變量在運行過程中變化,會造成多個單例類型實例的不一致,產(chǎn)生一些很奇怪的現(xiàn)象。
5、例如,某服務進程通過 檢查單例對象的某個屬性來停止多個線程服務,如果存在多個單例對象的實例, 就會造成部分線程服務停止,部分線程服務不能停止的情況。1.2單例對象的屬性更新通常,為了實現(xiàn)配置信息的實時更新,會有一個線程不停檢測配置文件或配 置數(shù)據(jù)庫的內(nèi)容,一旦發(fā)現(xiàn)變化,就更新到單例對象的屬性中。在更新這些信 息 的時候,很可能還會有其他線程正在讀取這些信息,造成意想不到的后果。還是以通過單例對象屬性停止線程服務為例, 如果更新屬性時讀寫不同步,可能訪問 該屬性時這個屬性正好為空(null ),程序就會拋出異常。解決方法2.1單例對象的初始化同步對于初始化的同步,可以通過如下代碼所采用的方式解決
6、。public class GlobalCo nfig private static GlobalConfig instance = nuII;private Vector properties = n ull;private GlobalConfig() /Load con figurati on in formatio n from DB or file /Set values for propertiesprivate static synchronized void synclnit() if (in sta nee = n ull) in sta nee = new GlobalC
7、on fig();public static GlobalC onfig get In sta nee() if (in sta nee = n ull) syncln it();retur n in sta nee;publie Veetor getProperties() retur n properties;這種處理方式雖然引入了同步代碼,但是因為這段同步代碼只會在最開始的 時候執(zhí)行一次或多次,所以對整個系統(tǒng)的性能不會有影響。2.2單例對象的屬性更新同步為了解決第2個問題,有兩種方法:1,參照讀者/寫者的處理方式設置一個讀計數(shù)器,每次讀取配置信息前,將計數(shù)器加1,讀完后將計數(shù)器減1.只有
8、在讀計數(shù)器為0時,才能更新數(shù)據(jù),同時要阻塞所有讀屬性的調(diào)用。 代碼如下。publie elass GlobalCo nfig private statie GlobalConfig instanee; private Veetor properties = nu II;private boolea n isUpdati ng = false; private int readCo unt = 0;private GlobalCo nfig() /Load eonfiguration information from DB or file /Set values for propertiespr
9、ivate statie synchronized void synclnit() if (in sta nee = n ull) in sta nee = new GlobalC on fig();public statie GlobalC onfig get In sta nee() if (in sta nee=n ull) syncln it();return in sta nee;public synchroni zed void update(Stri ng p_data) syn cUpdate ln();/Update propertiesprivate synchroni z
10、ed void syn cUpdate ln() while (readCou nt > 0) try wait(); catch (Excepti on e) private synchroni zed void syn cRead ln() readCo un t+;private synchroni zed void syn cReadOut() readCo un t-;n otifyAII();public Vector getProperties() syn cReadI n();/Process datasyn cReadOut();retur n properties;2
11、,采用"影子實例"的辦法具體說,就是在更新屬性時,直接生成另一個單例對象實例,這個新生成的 單例對象實例將從數(shù)據(jù)庫或文件中讀取最新的配置信息;然后將這些配置信息直 接賦值給舊單例對象的屬性。如下面代碼所示。public class GlobalCo nfig private static GlobalConfig instance = nuII;private Vector properties = n ull;private GlobalConfig() /Load con figurati on in formatio n from DB or file /Set va
12、lues for propertiesprivate static synchronized void synclnit() if (in sta nee = n ull) in sta nee = new GlobalC on fig();public static GlobalC onfig get In sta nee() if (in sta nee = n ull) syncln it();retur n in sta nee;publie Veetor getProperties() retur n properties;publie void updateProperties()
13、 /Load updated con figurati on in formati on by new a GlobalC onfig objectGlobalC onfig shadow = new GlobalC on fig(); properties = shadow.getProperties();注意:在更新方法中,通過生成新的 GlobalCo nfig的實例,從文件或數(shù)據(jù) 庫中得到最新配置信息,并存放到 properties屬性中。上面兩個方法比較起來,第二個方法更好,首先,編程更簡單;其次,沒有 那么多的同步操作,對性能的影響也不大。2、單例模式2java模式之單例模式:單例
14、模式確保一個類只有一個實例,自行提供這個實例并 向整個系統(tǒng)提供這個實例。特點:1 , 一個類只能有一個實例2,自己創(chuàng)建這個實例3,整個系統(tǒng)都要使用這個實例例:在下面的對象圖中,有一個"單例對象",而"客戶甲"、"客戶乙"和 "客戶丙"是單例對象的三個客戶對象??梢钥吹?,所有的客戶對象共享一個單例 對象。而且從單例對象到自身的連接線可以看出,單例對象持有對自己的引用。Singleton 模式主要作用是保證在Java應用程序中,一個類Class只有 一個實例存在。在很多操作中,比如建立目錄數(shù)據(jù)庫連接都需要這樣的單線程操
15、作。一些資源管理器常常設計成單例模式。外部資源:譬如每臺計算機可以有若干個 打印機,但只能有一個Printer Spooler,以避免兩個打印作業(yè)同時輸出到打印機中。每臺計算機可以有若干個通信端口,系統(tǒng)應當集中管理這些通信端口,以避免一個通信端口被兩個請求同時 調(diào)用。內(nèi)部資源,譬如,大多數(shù)的軟件都有一個(甚至多個)屬性文件存放系統(tǒng) 配置。這樣的系統(tǒng)應當由一個對象來管理這些屬性文件。一個例子:Win dows回收站。在整個視窗系統(tǒng)中,回收站只能有一個實例,整個系統(tǒng)都使用這個惟一的實例, 而且回收站自行提供自己的實例。因此,回收站是單例模式的應用。兩種形式:1,餓漢式單例類public class
16、 Sin glet on private Si nglet on()/在自己內(nèi)部定義自己一個實例,是不是很奇怪?/注意這是private 只供內(nèi)部調(diào)用private static Sin glet on in sta nee = new Sin gleto n();/這里提供了一個供外部訪問本class的靜態(tài)方法,可以直接訪問public static Sin glet on get In sta nce() return in sta nee;2,懶漢式單例類public class Sin glet on private static Sin glet on in sta nee = n
17、ull;public static synchroni zed Sin glet on get In sta nce() /這個方法比上面有所改進,不用每次都進行生成對象,只是第一次/使用時生成實例,提高了效率!if (in sta nce=n ull)in sta nee = newSin gleto n();retur n in sta nee;第二中形式是lazy initialization,也就是說第一次調(diào)用時初始 Singleton ,以后就不用再生成了。注意至U lazy initialization形式中的 synchronized,這個 synchronized 很重要,如果
18、沒有synchronized,那么使用getlnstance() 是有可能得到多個 Sin gleto n 實例。一般來說第一種比較安全。用單例模式實現(xiàn)的java連接MySql數(shù)據(jù)庫package com.adrop.util;import java.sql.*;public class DBMa nager /用戶名 private String user =/密碼 private String password =""/主機 private String host =""/數(shù)據(jù)庫名字 private String database ="&q
19、uot; /private DBMa nager dbm=n ull;/* private String url="jdbc:mysql:/"+host+"/"+"useU nicode=true&characterE ncodi ng=GB231 2"*/ private String url =""private Connection con = n ull;Stateme nt stmt;/*私有的構造方法,保證外部不能實例化,只能由DBManager自己能提供自*己的實例,并且只能有一個。*根據(jù)主機
20、、數(shù)據(jù)庫名稱、數(shù)據(jù)庫用戶名、數(shù)據(jù)庫用戶密碼取得連接。* param host String* param database String* param user Stri ng* param password String*/ private DBMa nager(Stri ng host, String database, String user, String password) this.host = host;this.database = database;this.user = user;this.password = password;/顯示中文 this.url = "
21、;jdbc:mysql:" + host + "/" + database +"?useU nicode=true&characterE ncodi ng=GB2312"try Class.forName("org.gjt.mm.mysql.Driver");catch (ClassNotF oun dExcepti on e) System.err.pri ntl n("class not foun d:" + e.getMessage();try con = DriverManager.getConnection(this.url, this.user, this.password);/ 連接類型為 ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLYstmt = co n.createStateme nt(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025陜西省安全員知識題庫附答案
- 華能電廠采購合同范本
- 個人投資項目合同范本
- 2025河北省安全員-C證(專職安全員)考試題庫
- 廠家金融分期購車合同范本
- 勞動合同范本美容
- 卡口抓拍合同范本
- 鄉(xiāng)村勞務服務合同范本
- 加盟餐飲合同范本
- 2025年吉林省安全員知識題庫及答案
- 蘇教版科學五年級下15《升旗的方法》教案
- 現(xiàn)代工業(yè)發(fā)酵調(diào)控緒論
- 超高性能混凝土項目立項申請(參考模板)
- 電纜橋架招標文件范本(含技術規(guī)范書)
- 試車場各種道路施工方案設計
- 部編版四年級語文下冊第二單元《習作:我的奇思妙想》課件PPT
- PS零基礎入門學習教程(適合純小白)PPT課件
- XX輸變電工程公司作業(yè)風險評估數(shù)據(jù)庫(精品模板)
- 涂裝行業(yè)常用日語單詞集
- 頭頸部影像學表現(xiàn)(詳細、全面)
- 《國際商務》PPT課件.ppt
評論
0/150
提交評論