java設計模式--單例模式

一 概念

這種模式涉及到一個單一的類,該類負責創(chuàng)建自己的對象,同時確保只有單個對象被創(chuàng)建。這個類提供了一種訪問其唯一的對象的方式,可以直接訪問,不需要實例化該類的對象

  • 單例類只能有一個實例
  • 單例類必須自己創(chuàng)建自己的唯一實例
  • 單例類必須給所有其他對象提供這一實例

關鍵點:

  • 構造函數(shù)為私有的
  • getIntence()方法中需要使用同步鎖synchronized防止多線程同時進入造成instance被多次實例化
  • 使用場景:參考單例模式|菜鳥教程

二 單例模式的幾種實現(xiàn)方式

1.懶漢式,線程不安全

是否Lazy初始化:是
是否多線程安全:否
缺點:lazy loading很明顯,線程不安全,多線程下無法正常工作

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

2.懶漢式,線程安全

是否 Lazy 初始化:是
是否多線程安全:是
優(yōu)點:第一次調(diào)用才初始化,避免內(nèi)存浪費。
缺點:必須加鎖 synchronized 才能保證單例,但加鎖會影響效率。

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

3.餓漢式

是否 Lazy 初始化:否
是否多線程安全:是
實現(xiàn)難度:易
描述:這種方式比較常用,但容易產(chǎn)生垃圾對象。
優(yōu)點:沒有加鎖,執(zhí)行效率會提高。
缺點:類加載時就初始化,浪費內(nèi)存。
它基于 classloder 機制避免了多線程的同步問題,不過,instance 在類裝載時就實例化,雖然導致類裝載的原因有很多種,在單例模式中大多數(shù)都是調(diào)用 getInstance 方法, 但是也不能確定有其他的方式(或者其他的靜態(tài)方法)導致類裝載,這時候初始化 instance 顯然沒有達到 lazy loading 的效果。

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
    return instance;  
    }  
}

4.雙檢鎖/雙重校驗鎖(DCL,即 double-checked locking)

是否 Lazy 初始化:是
是否多線程安全:是
實現(xiàn)難度:較復雜
描述:這種方式采用雙鎖機制,安全且在多線程情況下能保持高性能。
getInstance() 的性能對應用程序很關鍵。

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
    public void say(){
        System.out.println("hello word");
    }
} 

調(diào)用:

public static void main(String[] args) {
        Singleton singleton = Singleton.getSingleton();
        singleton.say();
    }

運行結果:

hello word
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

  • Java設計模式——單例模式 單例模式應該是大家最為熟知的一種設計模式了,相信大家或多或少的都在自己的項目中使用過...
    gogoingmonkey閱讀 572評論 0 2
  • 眾所周知,在代碼中采用合理的設計模式,不僅僅能使代碼更容易被他人理解,同時也能使整體模塊擁有更合理的結構,方便后期...
    JeromeLiee閱讀 339評論 0 1
  • 單例模式在我們?nèi)粘i_發(fā)中算是使用頻率最高的設計模式了,為什么單例模式的使用頻率會這么高呢? 有時我們的對象會占用一...
    MrKing5946閱讀 231評論 0 0
  • 許多時候整個系統(tǒng)只需要擁有一個的全局對象,這樣有利于我們協(xié)調(diào)系統(tǒng)整體的行為,這時就需要用到單例模式。在應用這個模式...
    留給時光吧閱讀 207評論 0 0
  • 我們給父視圖添加一個tap手勢,在點擊子視圖的時候會響應手勢. 產(chǎn)生這種問題的原因是子視圖不能交互,響應鏈遞歸傳導...
    不慌_閱讀 1,843評論 0 0

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