java单例模式_在Java中实现单例模式
該單例模式保證只有一個(gè)帶有全局訪問(wèn)點(diǎn)對(duì)象可以在給定的時(shí)間實(shí)例被創(chuàng)建。這是面向?qū)ο缶幊讨凶畛S玫募夹g(shù)之一。雖然它很簡(jiǎn)單,也許從類設(shè)計(jì)的角度來(lái)看最簡(jiǎn)單,但在嘗試實(shí)現(xiàn)它們之前,必須先了解一些微妙的問(wèn)題。本文將深入探討這種模式,引用Java代碼示例。
概觀
在某種情況下,系統(tǒng)應(yīng)該只允許一個(gè)類的一個(gè)對(duì)象在給定的時(shí)間點(diǎn)存在于內(nèi)存中。這意味著,當(dāng)程序?qū)嵗搶?duì)象時(shí),不應(yīng)該允許程序創(chuàng)建該類的其他對(duì)象。例如,在連接到數(shù)據(jù)庫(kù)的系統(tǒng)中,僅使用一個(gè)對(duì)象來(lái)管理數(shù)據(jù)庫(kù)連接。這可確保其他對(duì)象無(wú)法初始化不必要的連接,這會(huì)因多次實(shí)例化而松弛系統(tǒng)的整體性能。通過(guò)創(chuàng)建多個(gè)JDBC連接并觀察性能,可以非常輕松地對(duì)此進(jìn)行測(cè)試。表現(xiàn)肯定會(huì)受到影響或明顯放緩。單例模式基本上保證系統(tǒng)只創(chuàng)建一個(gè)類的實(shí)例。
單例模式
使用單例模式是一種標(biāo)準(zhǔn)技術(shù),可確保為給定類實(shí)例化一個(gè)且僅一個(gè)對(duì)象。它是Gang of Four討論的二十四種設(shè)計(jì)模式之一。我們的想法是解決諸如實(shí)例化類的單個(gè)實(shí)例,訪問(wèn)類的唯一實(shí)例或控制類實(shí)例化過(guò)程等問(wèn)題。實(shí)現(xiàn)此目標(biāo)的關(guān)鍵技術(shù)是使用私有修飾符隱藏構(gòu)造函數(shù),并提供應(yīng)用檢查和驗(yàn)證的方法,以確保只創(chuàng)建該類的一個(gè)實(shí)例。
這很簡(jiǎn)單但有效地滿足了需求。事實(shí)上,通過(guò)應(yīng)用相同的原則,我們可以控制創(chuàng)建的類的實(shí)例數(shù),而不僅限于單個(gè)實(shí)例。但是,這里我們只關(guān)注單個(gè)實(shí)例。
使用單例模式
不難發(fā)現(xiàn)我們實(shí)際上只需要內(nèi)存中一個(gè)類的一個(gè)實(shí)例的情況。多個(gè)對(duì)象可能會(huì)破壞原因或?qū)φ谶\(yùn)行的應(yīng)用程序的性能造成嚴(yán)重破壞。在面向?qū)ο蟮木幊讨?#xff0c;正在運(yùn)行的應(yīng)用程序通常在存儲(chǔ)器中具有許多對(duì)象,在執(zhí)行中交互并扮演關(guān)鍵部分。但是,當(dāng)實(shí)現(xiàn)線程池,緩存,對(duì)話框或處理首選項(xiàng)和注冊(cè)表設(shè)置的對(duì)象,數(shù)據(jù)庫(kù)連接,日志記錄,充當(dāng)外圍設(shè)備或圖形卡的設(shè)備驅(qū)動(dòng)程序的對(duì)象等都是我們想要的情況運(yùn)行對(duì)象的單個(gè)實(shí)例; 否則,它會(huì)產(chǎn)生很多問(wèn)題,如資源堵塞,內(nèi)存過(guò)載和許多其他不一致的行為。
實(shí)現(xiàn)單例模式
這是模式的快速實(shí)現(xiàn)。
public final class Singleton { private static final Singleton singleInstance = new Singleton(); private Singleton(){ } public static Singleton getInstance(){ return singleInstance; }}public class TestSingleton { public static void main(String[] args){ Singleton s1; Singleton s2; s1 = Singleton.getInstance(); s2 = Singleton.getInstance(); if(s1 == s2){ System.out.println("References to same Singleton object"); } }}該singleton類被聲明為final所以沒(méi)有子類可以被創(chuàng)建。即使通過(guò)對(duì)此類進(jìn)行子類化,這也會(huì)限制多個(gè)實(shí)例化。構(gòu)造函數(shù)被聲明為private; 因此,只有Singleton類可以使用此構(gòu)造函數(shù)創(chuàng)建Singleton對(duì)象。對(duì)Singleton對(duì)象的靜態(tài)引用調(diào)用私有構(gòu)造函數(shù),并僅傳遞該類的一個(gè)實(shí)例。在調(diào)用getInstance()方法時(shí),僅接收對(duì)象的引用副本。
在這里,我們通過(guò)創(chuàng)建另一個(gè)名為TestSingleton的類來(lái)使用簡(jiǎn)單的測(cè)試。此類聲明兩個(gè)引用Singleton對(duì)象并調(diào)用getInstance()方法。然后,我們比較兩個(gè)引用以確保它們實(shí)際引用相同的運(yùn)行時(shí)實(shí)例而不是兩個(gè)不同的對(duì)象。
有時(shí),我們需要一個(gè)只在第一個(gè)靜態(tài)方法被調(diào)用而不是之前創(chuàng)建實(shí)例的實(shí)現(xiàn)。在前面的示例中,對(duì)象是靜態(tài)創(chuàng)建的; 在的getInstance()方法簡(jiǎn)單地返回引用中的作用。在這種情況下,我們希望在第一次調(diào)用時(shí)創(chuàng)建對(duì)象,稱為延遲初始化。此外,我們希望調(diào)用是線程安全的 ; 否則,它可能導(dǎo)致奇怪的不穩(wěn)定行為或內(nèi)存泄漏,從而導(dǎo)致JVM崩潰。這是實(shí)現(xiàn)這一目標(biāo)的例子。
public final class Singleton { private static volatile Singleton singleInstance = null; private Singleton(){ } public static Singleton getInstance(){ if (singleInstance == null) { synchronized(Singleton.class) { if (singleInstance == null) { singleInstance = new Singleton(); } } } return singleInstance; }}public class TestSingleton { public static void main(String[] args){ Singleton s1; Singleton s2; s1 = Singleton.getInstance(); s2 = Singleton.getInstance(); if(s1 == s2){ System.out.println("References to same Singleton object"); } }}單例也可以使用Enum實(shí)現(xiàn)。實(shí)際上,在可能的情況下使用Enum通常更好,而不是使用類來(lái)實(shí)現(xiàn)單例模式。JVM保證只能從單例枚舉創(chuàng)建一個(gè)實(shí)例。
public enum SingletonEnum { SINGLEINSTANCE; public void someMethod(){ // ... }}public class TestSingleton { public static void main(String[] args){ SingletonEnum s1; SingletonEnum s2; s1 = SingletonEnum.SINGLEINSTANCE; s2 = SingletonEnum.SINGLEINSTANCE; if (s1 == s2){ System.out.println("References to same Singleton object"); } }}結(jié)論
一如既往,用戶自行決定是良好設(shè)計(jì)的關(guān)鍵,因?yàn)椴徽_使用單例模式可能會(huì)導(dǎo)致其他問(wèn)題; 如果它執(zhí)行復(fù)雜和重量級(jí)的操作,則很難測(cè)試單例。更好的建議是使用依賴注入框架來(lái)構(gòu)造單個(gè)對(duì)象。單例在諸如在GUI應(yīng)用程序中創(chuàng)建對(duì)話框或者幾乎沒(méi)有機(jī)會(huì)擁有并發(fā)用戶的情況下效果最佳。單例模式雖然有用,但卻因在大型可伸縮應(yīng)用程序中創(chuàng)建性能瓶頸而臭名昭著。
整理不易,請(qǐng)大家多多評(píng)論轉(zhuǎn)發(fā)和關(guān)注,您的支持是我最大的動(dòng)力。
總結(jié)
以上是生活随笔為你收集整理的java单例模式_在Java中实现单例模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java执行exe 没捕获到输出_Jav
- 下一篇: group by 和 left join