單例模式——個(gè)人學(xué)習(xí)

單例模式

一個(gè)類(lèi)僅有一個(gè)實(shí)例,所有其他類(lèi)對(duì)象共享該實(shí)例進(jìn)行操作

特點(diǎn):只能由自己的公共方法創(chuàng)建一個(gè)實(shí)例,只對(duì)外提供該唯一實(shí)例

應(yīng)用場(chǎng)景:資源共享文件與控制資源的操作(如日志文件,應(yīng)用配置,數(shù)據(jù)庫(kù)連接池,線程池)

應(yīng)用實(shí)例:windows task manager,數(shù)據(jù)庫(kù)連接池,OS的文件系統(tǒng),回收站...

實(shí)現(xiàn)方法:餓漢,懶漢(飽漢),雙檢索,靜態(tài)內(nèi)部類(lèi),枚舉類(lèi)

  • 懶漢模式只有需要單例時(shí)才去初始化實(shí)例,線程一般不安全
  • 餓漢模式在類(lèi)加載階段就將實(shí)例初始化完成,這樣保證線程安全
  • 雙檢查模式,不是對(duì)這個(gè)方法進(jìn)行synchronize,僅僅在實(shí)例化步驟前進(jìn)行2次synchronize該類(lèi)
  • 靜態(tài)內(nèi)部類(lèi),保證了線程安全,在內(nèi)部類(lèi)中實(shí)例化唯一實(shí)例,讀取實(shí)例沒(méi)有同步保證性能
  • 枚舉模式,默認(rèn)線程安全

相關(guān)問(wèn)題:

  • clone能否產(chǎn)生一個(gè)新的單例模式類(lèi)的實(shí)例?
    不能,單例類(lèi)必須是final的不能被繼承,同時(shí)假如單例類(lèi)繼承于有clone方法的類(lèi),需要重寫(xiě)clone,是它拋出異常
  • 在getInstance()方法上同步有優(yōu)勢(shì)還是僅同步必要的塊更優(yōu)優(yōu)勢(shì)?
    由于鎖有開(kāi)銷(xiāo),因此僅同步必要的塊(創(chuàng)建實(shí)例部分)就行了,其他時(shí)候僅僅是對(duì)實(shí)例的只讀操作,保證性能
  • 雙檢索有什么缺點(diǎn)?
    需要防止初始化實(shí)例時(shí),指令重排序,因此最好對(duì)指定變量使用volatile修飾,防止指令重排序(jdk5.0以后引入)
  • 如何獲取更多的單例對(duì)象,如何防止?
    反射機(jī)制,防止的辦法就是在構(gòu)造函數(shù)中判斷是第幾次被調(diào)用,假如不是首次調(diào)用就立即拋出異常。還有一個(gè)辦法就是使用枚舉類(lèi)模式實(shí)現(xiàn)單例
Constructor con = Singleton. class. getDeclaredConstruction( ) ;
con. setAccessible( true) ;
//通過(guò)反射獲取實(shí)例
Singleton instance = ( Singleton) con. newInstance( ) ;

枚舉類(lèi)型

  • 用來(lái)表示常量,作為switch的選擇類(lèi)型,繼承自java.lang.Enum,因此不能繼承其他類(lèi)
  • 在類(lèi)中添加其他方法,方法必須在實(shí)例后面,最后一個(gè)實(shí)例后需要接";"
  • 枚舉集合:java.util.EnumSet,java.util.EnumMap

實(shí)現(xiàn)方法實(shí)踐

//單例模式的實(shí)現(xiàn)方式

// 懶漢(飽漢),一般沒(méi)有對(duì)方法同步,多線程可能存在生成多個(gè)實(shí)例,優(yōu)點(diǎn)是效率高,但是不安全,
// 有時(shí)候直接類(lèi)加載就初始化靜態(tài)變量,浪費(fèi)內(nèi)存
class Singleton{ 
    private static Singleton singleton;
    private Singleton(){};

    public static Singleton getInstance(){
        if(singleton == null){
            singleton = new Singleton();
        }
        return singleton;
    }
}

//餓漢,類(lèi)加載就產(chǎn)生實(shí)例
class Singleton{ 
    private static Singleton singleton = new Singleton();
    private Singleton(){};

    public static synchronized Singleton getInstance(){
        return singleton;
    }
}

//雙重檢測(cè),對(duì)實(shí)例化塊進(jìn)行2次檢驗(yàn),使用同步
class Singleton{ 
    private static volatile Singleton singleton;
    private Singleton(){};

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

//靜態(tài)內(nèi)部類(lèi),不用使用同步,線程安全.內(nèi)部類(lèi)私有性質(zhì)保證只有g(shù)etInstance能夠調(diào)用它
class Singleton{ 
    
    private static class SingletonHolder{
        private static final Singleton INSTANCE = new Singleton();
    } 

    private Singleton(){};

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

//枚舉類(lèi),默認(rèn)線程安全,這種方式絕對(duì)防止反射調(diào)用私有構(gòu)造器來(lái)破壞單例
public enum Singleton{
    INSTANCE;

    private String name;

    public void dosomething(){
        doing...
    }
}
最后編輯于
?著作權(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),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 單例模式(SingletonPattern)一般被認(rèn)為是最簡(jiǎn)單、最易理解的設(shè)計(jì)模式,也因?yàn)樗暮?jiǎn)潔易懂,是項(xiàng)目中最...
    成熱了閱讀 4,545評(píng)論 4 34
  • 前言 本文主要參考 那些年,我們一起寫(xiě)過(guò)的“單例模式”。 何為單例模式? 顧名思義,單例模式就是保證一個(gè)類(lèi)僅有一個(gè)...
    tandeneck閱讀 2,630評(píng)論 1 8
  • 1 場(chǎng)景問(wèn)題# 1.1 讀取配置文件的內(nèi)容## 考慮這樣一個(gè)應(yīng)用,讀取配置文件的內(nèi)容。 很多應(yīng)用項(xiàng)目,都有與應(yīng)用相...
    七寸知架構(gòu)閱讀 6,977評(píng)論 12 68
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類(lèi)相關(guān)的語(yǔ)法,內(nèi)部類(lèi)的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,775評(píng)論 18 399
  • 爬取豆瓣電影top250。 1. 單線程版 2. 多線程版 使用線程池 線程的創(chuàng)建和銷(xiāo)毀是一個(gè)比較重的開(kāi)銷(xiāo)。所以,...
    木一晟閱讀 920評(píng)論 0 0

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