單例模式是Java設計思想中最簡單的設計模式之一。這種類型的設計模式屬於創建型模式,它提供了一種創建對象最好的方式。這種模式的只設計到一個單一類。顧名思義,單例模式就是類的實例全局只有一個。
這裏引用 菜鳥教程 的介紹:
用圖:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
主要解決:一個全局使用的類頻繁地創建與銷燬。
何時使用:當您想控制實例數目,節省系統資源的時候。
如何解決:判斷系統是否已經有這個單例,如果有則返回,如果沒有則創建。
關鍵代碼:構造函數是私有的。
優點: 1、在內存裏只有一個實例,減少了內存的開銷,尤其是頻繁的創建和銷燬實例(比如管理學院首頁頁面緩存)。 2、避免對資源的多重佔用(比如寫文件操作)。
缺點:沒有接口,不能繼承,與單一職責原則衝突,一個類應該只關心內部邏輯,而不關心外面怎麼樣來實例化。
使用場景: 1、要求生產唯一序列號。 2、WEB 中的計數器,不用每次刷新都在數據庫里加一次,用單例先緩存起來。 3、創建的一個對象需要消耗的資源過多,比如 I/O 與數據庫的連接等。
注意事項:getInstance() 方法中需要使用同步鎖 synchronized (Singleton.class) 防止多線程同時進入造成 instance 被多次實例化。
單例模式分爲兩種
懶漢模式:只有當實例被使用時,才加載單例對象。具體代碼如下:
//單例類
public class Sky {
//類的構造方法爲私有的,外部不能直接new。
private Sky(){}
//懶漢模式
//先聲明單例對象,必須爲靜態對象。
private static Sky sky = null;
/*
* 獲取單例的方法。
* 爲保證多線程下獲取的對象爲同一個對象,需要同步鎖,
* 該方法必須是靜態方法。
*/
public static synchronized Sky instance(){
if( sky == null){
sky = new Sky();
}
return sky;
}
}
懶漢模式下,外部要想獲取該類單例對象,只能通過類名調用instance()方法。相對於惡漢模式:在不使用該實例時,不佔用內存資源。但是多線程時,需要通過同步手段達到實例的唯一性,效率低。
餓漢模式:實例事先創建好,直接調用。具體實現如下:
//單例類
public class Sky {
//類的構造方法爲私有的,外部不能直接new。
private Sky(){}
//餓漢模式
//先聲明單例對象並且賦值,必須爲靜態對象
private static Sky sky =new Sky();
/*
* 獲取單例的方法。
* 返回值爲事先創建好的對象。
*/
public static Sky instance(){
return sky;
}
}
餓漢模式下,外部要想獲取該類單例對象,只能通過類名調用instance()方法。相對於懶漢模式:實例事先創建好,不使用該實例時,佔用內存資源。但是多線程訪問期間,效率快。