什么是單例模式?
定義:確保一個類只有一個實例,而且自行實例化並向整個系統提供這個實例場景,也就是說:確保某個類有且只有一個對象的場景,避免產生多個對象消耗過多的資源,或者某種類型的對象應該有且只有一個。
UML類圖:

構建單例模式的關鍵:
1.構造函數不對外開放,一般為Private
2.通過一個靜態方法或者枚舉返回單例類對象
3.確保單例類的對象有且只有一個,尤其是多線程的環境下
4.確保單例類對象在反序列化時不會重新構建對象
單例模式構建方式:
1.餓漢模式
2.懶漢模式(Double Check)
3.靜態內部類的單利模式
4.枚舉單例模式
5.容器實現單例模式
代碼示例:
1.餓漢模式
- public class Singleton {
- private Singleton(){
- }
- private static final Singleton Instance=new Singleton();
- public Singleton getInstance(){
- return Instance;
- }
- }
2. 懶漢模式(Double Check)
- public class Singleton {
- private Singleton(){
- }
- private static Singleton Instance=null;
- public Singleton getInstance(){
- if(Instance==null){
- synchronized (Singleton.class) {
- if(Instance==null)
- {
- Instance=new Singleton();
- return Instance;
- }
- }
- }
- return Instance;
- }
- }
3.靜態內部類單例模式
- public class Singleton {
- private Singleton(){}
- private static Singleton getInstance(){
- return SingletonHolder.Instance;
- }
- /**
- * 靜態內部類
- */
- private static class SingletonHolder{
- private static final Singleton Instance = new Singleton();
- }
- }
當第一次加載Singleton類時,並不會初始化Instance,只有在第一次調用Singleton的getInstance方法時,才會導致 Instance 被初始化。第一次調用 getInstance 方法會導致虛擬機加載SingletonHolder類,這種方式不僅能夠確保線程安全,也能夠保證單例對象的唯一性,同時也延遲了單例對象的實例化,所以推薦使用這種方法。
4.枚舉單例
- public enum SingletonEnum{
- INSTANCE;
- public void doSomething(){
- System.out.println("do sth.");
- }
- }
5.使用容器實現單例模式
- public class SingletonManager {
- private static Map<String, Object> objMap = new HashMap<String, Object>();
- private SingletonManager(){ }
- //將多種單例類型注入到一個統一的管理類,在使用時根據key獲取對象對應類型的對象
- public static void registerService(String key, Object instance)
- {
- if(!objMap.containsKey(key)){
- objMap.put(key, instance);
- }
- }
- public static Object getService(String key){
- return objMap.get(key);
- }
- }
這種容器單例模式的實現,在Android中,我們使用的Context的getSystemService(key)的方式,就是利用的容器單例模式。eg:WIndowsManagerService、ActivityManagerService等等。在虛擬機第一次加載該類時,會注冊各種Service,這些服務以鍵值對的形式存儲在一個HashMap中,用戶使用時只需要根據key來獲取到對應的具體服務對象了。
