保證一個類只有一個實例,而且提供一個訪問該實例的全局訪問點數據庫
常見的應用場景
:編程
任務管理器。回收站。網站的計數器。操做系統的文件系統。在servlet編程中,每一個servlet也是單例模式,項目中,讀取配置文件的類,通常也只有一個對象,數據庫的鏈接池,Application對象等。優勢
:安全
因爲單例模式只生成一個實例,減小了系統開銷,當一個對象的產生須要比較多的資源時,如讀取配置文件,產生其餘資源對象時,則能夠經過在應用啓動時直接產生一個單例對象,而後永久駐留內存的方式來解決多線程
常見的五種單例模式的實現方式:
餓漢式(線程安全,調用效率高,可是不能延時加載)
懶漢式(線程不安全,調用效率不高,可是能夠延時加載)ide
其餘:
雙重檢測鎖式(因爲JVM底層內部模型緣由,偶爾會出問題,不建議使用)性能
靜態內部類式(線程安全,調用效率高,可是能夠延時加載)網站
枚舉單例(線程安全,調用效率高,不能延時加載)操作系統
比較
3d
餓漢式和懶漢式區別
一、線程安全:
餓漢式天生就是線程安全的,能夠直接用於多線程而不會出現問題,懶漢式自己是非線程安全的,爲了實現線程安全有幾種寫法
二、資源加載和性能:
餓漢式在類建立的同時就實例化一個靜態對象出來,無論以後會不會使用這個單例,都會佔據必定的內存,可是相應的,在第一次調用時速度也會更快,由於其資源已經初始化完成,而懶漢式顧名思義,會延遲加載,在第一次使用該單例的時候纔會實例化對象出來,第一次調用時要作初始化,若是要作的工做比較多,性能上會有些延遲,以後就和餓漢式同樣了。
單例必定就只會建立一個對象嗎?不必定。
若是有兩個類加載器加載了該單例類,則就可能會建立多個單例實例。
每一個類加載器都定義了一個命名空間,若是有兩個以上的類加載器,不一樣的類加載器有可能會加載同一個類,若是多個類加載器同時加載了該單例類,就有可能建立多個單例對象。
若是有這種狀況,咱們應該自行指定類加載器,並指向同一個類加載器。