1. 程式人生 > >Java中的10個單例模式訪問問題

Java中的10個單例模式訪問問題



什麼是Singleton類?你之前用過Singleton嗎?

Singleton是一個類,在整個應用程式中只有一個例項,並提供一個getInstance()方法來訪問單例例項。在JDK中有許多類是使用Singleton模式實現的,如java.lang.Runtime,它提供了getRuntime()方法來訪問它並用於獲得Java中的可用記憶體和總記憶體


哪些類是Singleton的候選者?Java中的Singleton是哪種類的?

在這裡,他們檢查候選人是否具有足夠的單身人士使用經驗。他是否熟悉Java中單例的優勢/劣勢或替代方案?
答:任何你希望整個應用程式可用的類,只有一個例項是可行的,可以成為Singleton的候選者。
其中一個例子就是
Runtime類,因為在整個Java應用程式中,只有一個執行時環境可以使Runtime Singleton成為正確的決定。另一個例子是GUI應用程式中的Popup等實用程式類,如果您想要顯示帶有訊息的彈出視窗,則可以在整個GUI應用程式上有一個PopUp類,並隨時獲取其例項,然後用訊息呼叫show()


你可以在Java中編寫Singleton類的getInstance()方法的程式碼嗎?

大多數java程式設計師在這裡都會失敗,因為你可以根據他們編寫的程式碼提出大量的後續問題。我見過很多程式設計師用雙重檢查鎖定編寫Singleton getInstance()方法,但他們並不十分熟悉在Java 5之前對單例的雙重檢查相關的警告。


答案:直到被問及時,不要使用雙重檢查鎖定來編寫程式碼,因為它更復雜,錯誤的可能性更大,但如果您對雙重檢查鎖定有深入的瞭解,那麼揮發性變數和延遲載入比這是您發光的機會。我分享了使用列舉編寫單例類的程式碼示例,使用靜態工廠,並在我最近的帖子中使用了雙重檢查鎖定為什麼Enum Singleton在Java中更好,請看看那裡。
Java中的Singleton設計模式面試問題

使整個getInstance()方法同步還是僅僅關鍵部分足夠好?哪一個你會更喜歡?

這真的是一個很好的問題,我主要要求快速檢查候選人是否意識到效能會受到不必要的鎖定影響。由於鎖定只有在我們需要建立例項和其餘時間時才有意義,因為它只是讀取訪問許可權,所以鎖定關鍵部分總是更好的選擇。閱讀有關同步的更多資訊
如何使用Java進行同步答案:這又與雙重檢查的鎖定模式有關,良好的同步成本很高,並且當您將整個方法應用於getInstance()方法時,將會同步並滿足它。由於同步只在單例例項的初始化期間需要,為了防止建立單例的另一個例項,最好只同步臨界區而不是整個方法。單例模式也與工廠設計模式密切相關,其中getInstance()充當靜態工廠方法。



什麼是Singleton的懶惰和早期載入,你將如何實現它?

這是另一個很好的Singleton面試問題,它在理解與Java類載入相關的載入概念和成本方面的問題。我接受採訪的其中許多人並不十分熟悉這一點,但它很瞭解這個概念。

回答:由於有很多方法可以實現Singleton,比如使用雙重檢查鎖定或Singleton類以及在類載入期間初始化靜態 最終例項。前者稱為延遲載入,因為Singleton例項僅在客戶端呼叫getInstance()方法時建立,而後者稱為提前載入,因為Singleton例項在將類載入到記憶體中時建立。



給我一些來自Java Development Kit的Singleton模式的例子嗎?

這是所有人都公開的問題,請在JDK中分享哪些類是Singleton。這個問題的答案是java.lang.Runtime答案:Java開發工具包中有許多類是使用單例模式編寫的,下面是其中的幾個:
  1. Java.lang.Runtime with getRuntime() method 
  2. Java.awt.Toolkit with getDefaultToolkit() 
  3. Java.awt.Desktop with getDesktop() 

Singleton中的雙重檢查鎖定是什麼?

關於Singleton模式的一個最被誇大的問題,並且真正需要完全理解才能正確使用它,因為Java 5之前的Java Memory模型警告說明了這個問題。如果一個人想出了使用volatile關鍵字與Singleton例項並解釋它的解決方案,那麼它真的表明它對Java記憶體模型有深入的瞭解,並且他不斷更新他的Java知識。

答案:雙重檢查鎖定是一種技術,用於在多執行緒環境中呼叫getInstance()方法時阻止建立另一個Singleton例項在下面的例子中顯示的雙重檢查鎖定模式中,單例例項在初始化之前檢查兩次。請參閱此處以瞭解有關Java中的雙重檢查鎖定的更多資訊。 
public static Singleton getInstance(){
      if_INSTANCE == null){
         synchronized(Singleton .class){
          //雙重檢查鎖定 - 因為第二次檢查Singleton例項的鎖定
                if_INSTANCE == null){_
                     INSTANCE  =  new  Singleton();
                }
            }
         }
     return  _INSTANCE ;
}

只有當您需要延遲初始化時才應使用雙重檢查鎖定,否則使用Enum來實現單例或簡單靜態最終變數。



你如何防止使用clone()方法建立另一個Singleton例項?

這種型別的問題通常會問一些問題,比如如何打破單例或Singleton在Java中不是Singleton。
答案:首選的方法不是實現Cloneable介面,為什麼要建立Singleton的clone(),以及如果只是從clone()方法丟擲Exception 作為“無法建立Singleton類的克隆”。



你如何防止使用反射建立另一個Singleton例項?

向所有人開放。在我看來,從建構函式中丟擲異常是一個選項。
答案:這與之前的面試問題類似。由於Singleton類的建構函式應該是私有的,它可以防止從外部建立Singleton例項,但Reflection可以訪問私有的欄位和方法,這會開啟另一個例項的威脅。這可以通過從建構函式中丟擲Exception作為“Singleton已經初始化”來避免



如何防止在序列化過程中建立另一個Singleton例項?

另一個需要知道Java中序列化知識的好問題,以及如何使用它來儲存單例類。這對所有人都是開放的,但在我看來,使用readResolve()方法可以為你解決這個問題。
答案:您可以通過使用readResolve()方法來防止這種情況,因為在序列化過程中,readObject()用於建立例項,並且每次都會返回新例項,但是通過使用readResolve,您可以將其替換為原始Singleton例項。我已經在我的帖子Enum中以共享程式碼的方式將它作為Java中的Singleton。這也是我之所以說使用Enum來建立Singleton的原因之一,因為列舉的序列化由JVM來處理,並提供了保證。


什麼時候Singleton不是Java中的Singleton?

在Sun的Java站點中有一篇非常好的文章,它討論了Singleton實際上不存在時的各種情況。Singleton和Singleton的多個例項是可能的。這篇文章的連結http://java.sun.com/developer/technicalArticles/Programming/singletons/


除了這些關於Singleton模式的問題之外,我的一些讀者還貢獻了更多的問題,這些問題都包含在這裡。感謝你們的貢獻。


為什麼你應該避免使用單態反模式並用DI代替?

答案:單例依賴注入:每個需要訪問單例的類都通過建構函式或DI容器獲取物件。


為什麼辛格爾頓是反模式 

隨著越來越多的類呼叫getInstance(),程式碼變得越來越緊密,單一,不可測試,難以改變,難以重用,因為不可配置,隱藏的依賴關係。此外,如果您不經常呼叫getInstance(即一次),則不需要這種笨拙的雙重檢查鎖定


有多少種方法可以在Java中編寫Singleton類?

答案:我知道至少有四種方法可以在Java中實現Singleton模式
  1. 通過同步getInstance()方法來實現單例
  2. 帶有在類載入期間初始化的公共靜態final欄位的單例。
  3. 由靜態巢狀類生成的單例,也稱為Singleton持有者模式。
  4. 從使用列舉的Java 5上進行


如何在Java中編寫執行緒安全的Singleton?

答案:執行緒安全Singleton通常指的是寫入執行緒安全程式碼,如果同時由多個執行緒呼叫,則會建立一個且僅有一個Singleton例項。有很多方法可以通過使用上面顯示的雙重檢查鎖定技術以及使用通過類載入器初始化的Enum或Singleton 來實現此目的

最後幾個問題是你的實踐,由Mansi貢獻,謝謝Mansi 

14)Singleton vs Static Class?
15)什麼時候選擇Singleton over Static Class?
16)你可以用Java中的Static Class替換Singleton嗎?
17)java中單例和靜態類的區別?
18)Singleton優於靜態類的優點?


我在我的文章中討論了幾個這些問題的答案,即Singleton和Java中的靜態類 - 優點和缺點https://javarevisited.blogspot.com/2011/03/10-interview-questions-on-singleton.html