日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

單例模式

 天才白癡書館 2015-04-16
2015-04-14      0 個評論    來源:不給失敗找借口,只給成功想辦法  
收藏    我要投稿

單例模式

\

 

1) 單例的實現:

 

線程安全(加鎖):

上述代碼中的一個缺點是該類加載的時候就會直接new 一個靜態(tài)對象出來,當系統(tǒng)中這樣的類較多時,會使得啟動速度變慢?,F在流行的設計都是講“延遲加載”,我們可以在第一次使用的時候才初始化第一個該類對象。所以這種適合在小系統(tǒng)。

如果所使用的公用變量在多線程下沒有被保護機制時,變量結果會和理論值不一致,這樣就叫作線程不安全,相反公用變量在保護機制下工作,就不會出現未知變化,那這樣線程就是安全的.

單例中有個部分,就是有個對象作為這個類的成員變量被保存,而不是作為局部變量,所以其他方法發(fā)生并發(fā)訪問這個對象時其實是在操作同一個對象。

舉個例子,兩個人同時調用一個方法(給我蛋糕),但這個方法返回一個蛋糕的單例對象,兩個人同時獲得了同一個蛋糕,并坐下,舉起刀叉,結果第一個人先吞了蛋糕,就造成了第二個人明明得到了蛋糕,卻沒能吃到這個結果。

Tomcat可以用單例預熱。

傳統(tǒng)單例可以節(jié)省內存

\

為了線程安全:(使用同步鎖)

 

\

單鎖與雙鎖:

\

上述代碼中的一次鎖住了一個方法, 這個粒度有點大,改進就是只鎖住其中的new語句就OK。就是所謂的“雙重鎖”機制:

\

 

管理上的單例實現:(登記式單例)

\

本例子中利用Map里面存儲創(chuàng)建對象的id來阻止對象重復實例化。

什么時候用單例?無狀態(tài)的對象都可以作為單例。無數據的類似Service(無id那些),Dao是可以作為單例的,有數據的,如UserBean不可以。(如打印機)。還有類只有只讀數據(無set方法)可以作為單例:

\

還有如下應用情景:

1.Windows的TaskManager(任務管理器)就是很典型的單例模式(這個很熟悉吧),想想看,是不是呢,你能打開兩個windowstask manager嗎?不信你自己試試看哦~

2.windows的RecycleBin(回收站)也是典型的單例應用。在整個系統(tǒng)運行過程中,回收站一直維護著僅有的一個實例。

3. 網站的計數器,一般也是采用單例模式實現,否則難以同步。

4. 應用程序的日志應用,一般都何用單例模式實現,這一般是由于共享的日志文件一直處于打開狀態(tài),因為只能有一個實例去操作,否則內容不好追加。

5. Web應用的配置對象的讀取,一般也應用單例模式,這個是由于配置文件是共享的資源。

6. 數據庫連接池的設計一般也是采用單例模式,因為數據庫連接是一種數據庫資源。數據庫軟件系統(tǒng)中使用數據庫連接池,主要是節(jié)省打開或者關閉數據庫連接所引起的效率損耗,這種效率上的損耗還是非常昂貴的,因為何用單例模式來維護,就可以大大降低這種損耗。

7. 多線程的線程池的設計一般也是采用單例模式,這是由于線程池要方便對池中的線程進行控制。

8. 操作系統(tǒng)的文件系統(tǒng),也是大的單例模式實現的具體例子,一個操作系統(tǒng)只能有一個文件系統(tǒng)。

9. HttpApplication也是單位例的典型應用。熟悉ASP.Net(IIS)的整個請求生命周期的人應該知道HttpApplication也是單例模式,所有的HttpModule都共享一個HttpApplication實例.

10.說到門面類,就不能不提門面(Facade)模式??蛻舳伺c多個子系統(tǒng)的通信必須通過一個統(tǒng)一的門面(Facade)對象進行,這就是門面模式。這個統(tǒng)一的門面(Facade)對象就是門面類。在門面模式中,通常只需要一個門面類,并且此門面類只有一個實例,換言之它是一個單例類。但這不是絕對的。

寫單例時通用的規(guī)則:

1. 使類變成單例必須用static存放常量池。

一般在方法內定義:

 

是線程安全的,變量在棧中有個引用指向堆里的對象。

而向管理上的單例:

 

Map放在常量池在堆中,可以為多個線程訪問,線程不安全。

Servlet是單例的,在Servlet里面用privateString name;之類會因為do/get方法引發(fā)線程安全問題。第三方類庫要了解api可不可以做成單例。(有方法修改數據就不可作為單例)

單例模式也是一種比較常見的設計模式,它到底能帶給我們什么好處呢?其實無非是三個方面的作用:

第一、控制資源的使用,通過線程同步來控制資源的并發(fā)訪問;

第二、控制實例產生的數量,達到節(jié)約資源的目的。

第三、作為通信媒介使用,也就是數據共享,它可以在不建立直接關聯的條件下,讓多個不相關的兩個線程或者進程之間實現通信。

比如,數據庫連接池的設計一般采用單例模式,數據庫連接是一種數據庫資源

兩種單例:

1. 餓漢式

public class EagerSingleton

{

private static final EagerSingleton m_instance = newEagerSingleton();

/**

* 私有的默認構造子

*/

private EagerSingleton() { }

/**

* 靜態(tài)工廠方法

*/

public static EagerSingleton getInstance()

{

return m_instance;

}

}

2. 懶漢式

public class LazySingleton

{

private static LazySingleton m_instance = null;

/**

* 私有的默認構造子,保證外界無法直接實例化

*/

private LazySingleton() { }

/**

* 靜態(tài)工廠方法,返還此類的惟一實例

*/

synchronized public static LazySingleton getInstance()

{

if(m_instance == null)

{

m_instance = newLazySingleton();

}

return m_instance;

}

}

餓漢式是線程安全的,在類創(chuàng)建的同時就已經創(chuàng)建好一個靜態(tài)的對象供系統(tǒng)使用,以后不在改變

懶漢式如果在創(chuàng)建實例對象時不加上synchronized則會導致對對象的訪問不是線程安全的

推薦使用第一種

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多