1. 程式人生 > >Android單例模式你應該知道到一切

Android單例模式你應該知道到一切

前言

單例模式想必大家都使用過,但是也許你並不完全瞭解它,在這裡我就來詳細介紹一下所有的單例模式,及單例模式中涉及的一些細節問題。

一、單例模式的作用

保證了單利類的物件只有一個例項存在,利於協調系統整體的行為。

二、單利的模式的使用場景

確保某個類只有一個物件的場景,避免產生多個物件,消耗過多的資源,或者某種型別的物件應該只有一個。例如需要訪問IO和資料庫等資源時,就需要考慮使用單例模式。

三、單利模式的UML圖

這裡寫圖片描述

角色介紹:

(1)Client:客戶端,即呼叫者
(2)Singleton:單例類

實現單利類需要注意關鍵點如下:

(1)建構函式不對外開放,一般為private
(2)通過一個靜態方法或者列舉返回單利類的物件
(3)確保單利類的物件有且只有一個,尤其是在多執行緒下。
(4)確保單利類的物件在返序列化的時候不會重新構建物件。

四、單例模式的種類

單例模式主要分為以下幾種

1)餓漢模式

    /***
     * 餓漢式
     *
     * 優點:多執行緒安全
     * 缺點:提前載入記憶體,佔用記憶體。
     *
     */
    private static Singleton instance = new Singleton();
    private Singleton(){}

    public static Singleton getInstance(){
        return instance;
    }

2)懶漢模式1

    /***
     * 懶漢式
     * 
     * 優點:隨用隨載入
     * 缺點:多執行緒是不安全的
     *
     */
private static Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ if (instance == null){ instance = new Singleton(); } return instance; }

3)懶漢模式2

    /***
     * 懶漢式2:方法同步
     *
     * 優點:隨用隨載入,多執行緒安全
     * 缺點:第一次載入時需要及時進行初始化,反應慢。且每次呼叫getInstance時都進行了同步,造成不必要的開銷
     *
     */
private static Singleton instance = null; private Singleton(){} public static synchronized Singleton getInstance(){ if (instance == null){ instance = new Singleton(); } return instance; }

4)懶漢模式3

此種方法也是使用人數比較多的

    /***
     * 懶漢式3:Double Check Lock(DCL) 雙檢查鎖
     *
     * 優點:資源利用率高,隨用隨載入,多執行緒安全,2次判空,避免不必要的同步鎖,節省資源。
     * 缺點:第一次載入反應稍慢
     *
     * PS:volatile的作用:由於JDK1.5之前,JVM對於類的載入機制的問題會導致失效,在1.5之後加上此關鍵字可以保證DCL單利不失效。
     *
     */
    private volatile static Singleton instance = null;
    private Singleton(){}

    public static Singleton getInstance(){
        if (instance == null){
            synchronized(Singleton.class){
                if (instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

5)靜態內部類的單利模式

此種單利模式,推薦使用,效果好。

    /***
     * 靜態內部類的單利模式:推薦使用的模式
     *
     * 優點:多執行緒安全,延遲載入
     * 缺點:
     *
     */
    private Singleton(){}

    public static Singleton getInstance(){
        return SingletonHolder.instance;
    }

    /***
     * 靜態內部類
     */
    private static class SingletonHolder{
        private static final Singleton instance = new Singleton();
    }

6)列舉的單利模式

    /***
     * 列舉的單例模式
     *
     * 優點:寫法簡單,列舉預設是執行緒安全,並且在任何情況下它都只有一個例項,支援反序列化。
     * 缺點:
     *
     * PS:上面幾種單例模式在反序列化的時候都會生成新的物件,但是列舉不會。如果上面幾種方法要想反序列化
     * 的時候也不生成新的例項就需要重寫 readResolve()方法,如下:
     *
     * private Object readResolve() throws ObjectStreamException{
     * return instance;
     * }
     *
     */
    public enum SingletonEnum{
        INSTANCE;
    }

7)使用容器實現單利模式

    /***
      * 使用容器實現單例模式
      *
      * 優點:將多種單利型別放在統一的管理類中,使用使根據key獲取單利物件。降低使用者使用成本,也對使用者隱藏了具體實現,降低耦合
      * 缺點:
      *
      */
     public class SingletonManager{
        private static Map<String,Object> objMap = new HashMap<>();

         private SingletonManager(){}
         public static void registerSingleton(String key,Object instance){
             if (!objMap.containsKey(key)){
                 objMap.put(key,instance);
             }
         }

         public static Object getSingleton(String key){
             return objMap.get(key);
         }
     }

五、結語

不關以哪種方式實現的單利模式,他們的核心都是之前說到的4點
(1)建構函式不對外開放,一般為private
(2)通過一個靜態方法或者列舉返回單利類的物件
(3)確保單利類的物件有且只有一個,尤其是在多執行緒下。
(4)確保單利類的物件在返序列化的時候不會重新構建物件。

至於到底選擇哪種單例模式,試自己專案而定。

如有錯誤還請指出!(^o^)/~