單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種類型的設計模式屬于創建型模式,它提供了一種創建對象的最佳方式。
這種模式涉及到一個單一的類,該類負責創建自己的對象,同時確保只有單個對象被創建。這個類提供了一種訪問其唯一的對象的方式,可以直接訪問,不需要實例化該類的對象。
優點: 1、在內存里只有一個實例,減少了內存的開銷,尤其是頻繁的創建和銷毀實例(比如管理學院首頁頁面緩存)。 2、避免對資源的多重占用(比如寫文件操作)。
缺點:沒有接口,不能繼承,與單一職責原則沖突,一個類應該只關心內部邏輯,而不關心外面怎么樣來實例化。
注意:
- 單例類午餐的構造方法要私有化。
- 單例類只能有一個實例。
- 單例類必須自己創建自己的唯一實例。
- 單例類必須給所有其他對象提供這一實例。
實現方式:
1. 懶加載,線程不安全
/**
* 懶漢式,線程不安全
* @author mazaiting
*/
public class Singleton {
private static Singleton sSingleton;
private Singleton(){}
/**
* 獲取單例--多線程不能正常工作。
* @return 返回Singleton對象
*/
public static Singleton getInstance() {
if (null == sSingleton){
sSingleton = new Singleton();
}
return sSingleton;
}
}
2. 懶加載,線程安全
/**
* 懶漢式,線程安全
* @author mazaiting
*/
public class Singleton {
private static Singleton sSingleton;
private Singleton(){}
/**
* 獲取單例--必須加鎖 synchronized 才能保證單例,但加鎖會影響效率。
* @return 返回Singleton對象
*/
public static synchronized Singleton getInstance() {
if (null == sSingleton){
sSingleton = new Singleton();
}
return sSingleton;
}
}
3. 非懶加載,線程安全
/**
* 餓漢式,線程安全
* @author mazaiting
*/
public class Singleton {
private static Singleton sSingleton = new Singleton();
private Singleton(){}
/**
* 獲取單例--類加載時就初始化,浪費內存。
* @return 返回Singleton對象
*/
public static Singleton getInstance() {
return sSingleton;
}
}
4. Double Check Lock(DCL)--雙檢鎖/雙重校驗鎖
/**
* 雙檢鎖/雙重校驗鎖,線程安全
* @author mazaiting
*/
public class Singleton {
private static Singleton sSingleton;
private Singleton(){}
/**
* 獲取單例--這種方式采用雙鎖機制,安全且在多線程情況下能保持高性能。
* @return 返回Singleton對象
*/
public static Singleton getInstance() {
if (null == sSingleton) {
synchronized (Singleton.class) {
if (null == sSingleton) {
sSingleton = new Singleton();
}
}
}
return sSingleton;
}
}
5. 登記式/靜態內部類
/**
* 雙檢鎖/雙重校驗鎖,線程安全
* @author mazaiting
*/
public class Singleton {
private Singleton(){}
/**
* 獲取單例--這種方式能達到雙檢鎖方式一樣的功效,但實現更簡單。
* 對靜態域使用延遲初始化,應使用這種方式而不是雙檢鎖方式。
* 這種方式只適用于靜態域的情況,雙檢鎖方式可在實例域需要延遲
* 初始化時使用。
* @return 返回Singleton對象
*/
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
}
6. 枚舉
/**
* 枚舉--實現單例模式的最佳方法。它更簡潔,自動支持序列化機制,絕對防止多次實例化。
* @author mazaiting
*/
public enum Singleton {
INSTANCE;
private Singleton(){}
}