面試題2 實現Singleton模式

2021-07-15 09:59:52 字數 2885 閱讀 1848

題目:設計乙個類,我們只能生成該類的乙個例項

考察點:單例模式

知識點:主要介紹兩種:懶漢式、餓漢式單例。

單例模式有以下特點:

1.單例類只能有乙個例項。

2.單例類必須自己建立自己的唯一例項。

3.單例類必須給所有其他物件提供這一例項。

單例模式確保某個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。

在計算機系統中,執行緒池、快取、日誌物件、對話方塊、印表機、顯示卡的驅動程式物件常被設計成單例。

這些應用都或多或少具有資源管理器的功能。每台計算機可以有若干個印表機,但只能有乙個printer spooler,以避免兩個列印作業同時輸出到印表機中。每台計算機可以有若干通訊埠,系統應當集中管理這些通訊埠,以避免乙個通訊埠同時被兩個請求同時呼叫。總之,選擇單例模式就是為了避免不一致狀態,避免政出多頭。

1.懶漢式單例

//懶漢式單例類.在第一次呼叫的時候例項化自己 

public

class

singleton   

private

static

singleton single=

null

;  //靜態工廠方法 

public

static

singleton getinstance()     

return

single;  

}  } 

singleton通過將構造方法限定為private避免了類在外部被例項化,在同乙個虛擬機器範圍內,singleton的唯一例項只能通過getinstance()方法訪問。

但是以上懶漢式單例的實現沒有考慮執行緒安全問題,它是執行緒不安全的,併發環境下很可能出現多個singleton例項,要實現執行緒安全,有以下三種方式,都是對getinstance這個方法改造,保證了懶漢式單例的執行緒安全,如果你第一次接觸單例模式,對執行緒安全不是很了解,可以先跳過下面這三條,去看餓漢式單例,等看完後再回頭考慮執行緒安全的問題:

1.在getinstance方法上加同步

public static synchronized singleton getinstance()

return single;

}

2.雙重檢查鎖定

public

static

singleton getinstance()     

}    

}    

return

singleton;   

}  3.靜態內部類

public

class

singleton     

private

singleton (){}    

public

static

final

singleton getinstance()     

}    

這種比上面1、2都好一些,既實現了執行緒安全,又避免了同步帶來的效能影響。

2.餓漢式單例

//餓漢式單例,在類初始化時,已經自行例項化

public

class

singleton1   

private

static

final

singleton1 single = 

newsingleton1();  

//靜態工廠方法 

public

static

singleton1 getinstance()   

}  餓漢式在類建立的同時就已經建立好乙個靜態的物件供系統使用,以後不再改變,所以天生是執行緒安全的。

3.兩者的區別

從名字上看,餓漢和懶漢,餓漢就是類一旦載入,就把單例初始化完成,保證getinstance的時候,單例就是已經存在的,

而懶漢比較懶,只有當呼叫getinstance的時候,才回去初始化這個單例。

另外從以下兩點再區分以下這兩種方式:

a.執行緒安全

餓漢式天生就是執行緒安全的,可以直接用於多執行緒而不會出現問題,

懶漢式本身是非執行緒安全的,為了實現執行緒安全有幾種寫法,見上述。

b.資源載入

餓漢式單例在類建立的同時就例項化乙個靜態物件出來,不管之後會不會使用這個單例,都會佔據一定的記憶體,

但是相應的,在第一次呼叫時速度也會更快,因為其資源已經初始化完成。

而懶漢式顧名思義,會延遲載入,在第一次使用該單例的時候才會例項化物件出來,第一次呼叫時要做初始化,如果要做

的工作比較多,效能上就會有些延遲。

對於懶漢式中的三種實現又會有一些區別:

第一種,在方法呼叫上加了同步,雖然執行緒安全了,但是每次都要同步,會影響效能,畢竟大多數情況下是不需要同步的

第二種,在getinstance中做了兩次null檢查,確保了只有第一次呼叫單例的時候才會做同步,這樣也是執行緒安全的,

同時避免了每次都同步的效能損耗。

第3種,

利用了classloader的機制來保證初始化instance時只有乙個執行緒,所以也是執行緒安全的,同時沒有效能損耗

補充:執行緒安全

如果你的**所在的程序中有多個執行緒在同時執行,而這些執行緒可能會同時執行這段**。如果每次執行結果和單執行緒執行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是執行緒安全的。

或者說:乙個類或者程式所提供的介面對於執行緒來說是原子操作,或者多個執行緒之間的切換不會導致該介面的執行結果存在二義性,也就是說我們不用考慮同步的問題,那就是執行緒安全的。

面試題2 實現Singleton模式

題目 設計乙個類,我們只能生成該類的乙個例項。只能生成乙個例項的類是實現singleton 單例 模式的型別。由於設計模式在物件導向程式設計中起著舉足輕重的作用,面試中經常會出現這樣的面試題。不好得解決方法一 只適用於單執行緒環境 public sealed class singleton priv...

面試題2 實現Singleton模式

實現singleton模式 要求熟練掌握 單例模式的要求 類在記憶體中只能有乙個例項 1.該物件不能是全域性物件或者棧物件 2.該物件是乙個堆物件 靜態成員函式與普通成員函式的區別 單例模式的實現步驟 1.將建構函式私有化 2.在類中定義乙個靜態的指標物件,並在類外初始化為空 3.定義乙個返回值為類...

面試題2 實現Singleton模式

題目描述 設計乙個類,我們只能生成該類的乙個例項。解決方案 1.只適用於單執行緒環境 單執行緒環境下可以正常工作。但是在多執行緒環境下,如果兩個執行緒同時判斷到instance為null,那麼這兩個執行緒都會建立乙個例項,此時的singleton就不滿足單例模式的要求了。1 public seale...