設(shè)計(jì)模式--單例模式

單例模式

  1. 定義:確保一個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。
  2. 使用場景:確保一個(gè)類有且只有一個(gè)對(duì)象的場景,避免產(chǎn)生多個(gè)對(duì)象消耗過多的資源,或者某種類型的對(duì)象只應(yīng)該有且只有一個(gè)。
  3. 關(guān)鍵點(diǎn):
    • 構(gòu)造函數(shù)不對(duì)外開放,一般為 Private。
    • 通過一個(gè)靜態(tài)方法或者枚舉返回單例類對(duì)象 。
    • 確保單例類的對(duì)象有且只有一個(gè),尤其在多線程環(huán)境下。
    • 確保單例類對(duì)象在反序列化時(shí)不會(huì)重新構(gòu)建對(duì)象。
  4. 實(shí)現(xiàn)方式:
    1. 懶漢模式:
      • 定義:懶漢模式是聲明一個(gè)靜態(tài)對(duì)象,并且在用戶第一次調(diào)用個(gè)體Instance時(shí)進(jìn)行初始化。
      • 代碼實(shí)現(xiàn):
        public class SingleCode {
           //懶漢模式
           private static SingleCode instance;
           private SingleCode(){}
                public static synchronized SingleCode getInstance(){
                     if(instance == null ) {
                        instance = new SingleCode();
                       }
                       return instance;
                 }
          }
        
        
      • 優(yōu)點(diǎn):單例只有在使用時(shí)才會(huì)被實(shí)例化,在一定程度上節(jié)約資源。
      • 缺點(diǎn):第一次加載時(shí)需要即使進(jìn)行實(shí)例化,反應(yīng)稍慢,最大的問題時(shí)每次調(diào)用getInstance都進(jìn)行同步,造成不必要的同步開銷。
    2. Double CheckLock(DCL)實(shí)現(xiàn)單利:
      • 定義:DCL方式實(shí)現(xiàn)單例模式的優(yōu)點(diǎn)是既能夠在需要時(shí)才初始化單利,又能夠保證線程安全,且單例對(duì)象初始化后調(diào)用getInstance不進(jìn)行同步鎖;
      • 代碼實(shí)現(xiàn):
        public class SingleCode {
            //DCL 實(shí)現(xiàn)單例模式
            private static  SingleCode instance = null;
            private static Object obj = new Object();
            private SingleCode(){}
            public static SingleCode getInstance(){
                if(instance == null) {  //判斷是否為空避免不需要的同步
                    synchronized (obj) {
                        if(instance == null ) { //為了在null 的情況下創(chuàng)建實(shí)例
                            instance = new SingleCode();
                        }
                    }
                }
                return instance;
            }
        }
        
        
      • 優(yōu)點(diǎn):資源利用率高,第一次執(zhí)行g(shù)etInstance時(shí)單例對(duì)象才會(huì)被實(shí)例化,效率高。
      • 缺點(diǎn):第一次加載時(shí)反應(yīng)稍慢,也由于Java內(nèi)存模型的原因偶爾會(huì)失敗。
    3. 靜態(tài)內(nèi)部類單例模式:
      • 代碼實(shí)現(xiàn):
          public class SingleCode {
        
            //靜態(tài)內(nèi)部類實(shí)現(xiàn)單例模式
            private SingleCode(){}
            public static SingleCode getInstance(){
                return SingleHolder.instance;
            }
            /**靜態(tài)內(nèi)部類*/
            private static class SingleHolder{
                private static final SingleCode instance = new SingleCode();
            }
         }
        
        
      • 優(yōu)點(diǎn):第一次調(diào)用getInstance方法會(huì)導(dǎo)致虛擬機(jī)加載SingleHolder類,這種方法不僅能夠確保線程安全,也能夠保證單例對(duì)象的唯一性,同時(shí)也延遲里單例的實(shí)例化。
      • 推薦使用的單例模式實(shí)現(xiàn)方式。
    4. 枚舉單例:
      • 代碼實(shí)現(xiàn):
          public enum SingleEnum{
           INSTANCE;
           public void doSomething(){
              System.out.put("do sth.");  
           }
          
          }
        
      • 優(yōu)點(diǎn):寫法簡單,枚舉實(shí)例的創(chuàng)建是線程安全的,并且任何情況下它都是一個(gè)單例。
    5. 使用容器實(shí)現(xiàn)單例模式:
      • 代碼實(shí)現(xiàn):
        public class SingleManager {
            private static Map<String,Object> objMap = new HashMap<String, Object>();
            private SingleManager(){}
            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);
            }
        
        }
        
        
      • 優(yōu)點(diǎn) 容器實(shí)現(xiàn)單例模式可以管理多種類型的單例,并且在使用時(shí)可以通過統(tǒng)一接口進(jìn)行獲取操作,降低用戶使用成本,有對(duì)用戶隱藏了具體實(shí)現(xiàn),降低了耦合度。

總結(jié)

  1. 優(yōu)點(diǎn):
    • 由于單例模式在內(nèi)存中只有偶一個(gè)實(shí)例,減少內(nèi)存開支,特別是一個(gè)對(duì)象需要頻繁地創(chuàng)建、銷毀時(shí),而且創(chuàng)建或 銷毀時(shí)性能又無法優(yōu)化。
    • 由于單例模式只生成一個(gè)實(shí)例,所以減少系統(tǒng)的性能開銷。
    • 單例模式可以避免對(duì)資源的多重占用。
    • 單例模式可以在系統(tǒng)設(shè)置全局的訪問點(diǎn),優(yōu)化和共享資源訪問。
  2. 缺點(diǎn):
    • 單例模式一般沒有接口,擴(kuò)展很困難,若要擴(kuò)展除了修改代碼基本上沒有第二種途徑實(shí)現(xiàn)。
    • 單例對(duì)象如果持有Context,那么很容引發(fā)內(nèi)存泄露,此時(shí)需要注意傳遞給單例對(duì)象的Context最好是Application Context。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 單例模式(Singleton Pattern)是眾多設(shè)計(jì)模式中較為簡單的一個(gè),同時(shí)它也是面試時(shí)經(jīng)常被提及的問題,如...
    廖少少閱讀 651評(píng)論 0 1
  • 前言 本文主要參考 那些年,我們一起寫過的“單例模式”。 何為單例模式? 顧名思義,單例模式就是保證一個(gè)類僅有一個(gè)...
    tandeneck閱讀 2,628評(píng)論 1 8
  • 在Java設(shè)計(jì)模式中,單例模式相對(duì)來說算是比較簡單的一種構(gòu)建模式。適用的場景在于:對(duì)于定義的一個(gè)類,在整個(gè)應(yīng)用程序...
    時(shí)待吾閱讀 281評(píng)論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,578評(píng)論 19 139
  • 目錄 本文的結(jié)構(gòu)如下: 什么是單例模式 為什么要用該模式 模式的結(jié)構(gòu) 代碼示例 優(yōu)點(diǎn)和缺點(diǎn) 適用環(huán)境 模式應(yīng)用 總...
    w1992wishes閱讀 484評(píng)論 1 2

友情鏈接更多精彩內(nèi)容