欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實(shí)現(xiàn)單例模式的五種方法介紹

 更新時(shí)間:2023年01月31日 10:07:24   作者:Knight_AL  
單例模式確保某個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。在計(jì)算機(jī)系統(tǒng)中,線程池、緩存、日志對(duì)象、對(duì)話框、打印機(jī)、顯卡的驅(qū)動(dòng)程序?qū)ο蟪1辉O(shè)計(jì)成單例

餓漢式

立即加載

防止new對(duì)象,構(gòu)造私有,寫一個(gè)公共的方法返回對(duì)象

占用空間,線程安全

public class Singleton {
    /**
     * 私有構(gòu)造
     */
    private Singleton(){
        System.out.println("構(gòu)造函數(shù)Singleton");
    }
    private static Singleton singleton = new Singleton();
    public static Singleton getInstance(){
        return singleton;
    }
}

懶漢式

延遲加載

占用空間小,效率有問題,線程不安全

public class Singleton {
    /**
     * 私有構(gòu)造
     */
    private Singleton(){
        System.out.println("構(gòu)造函數(shù)Singleton");
    }
    private static Singleton singleton = null;
    public static Singleton getInstance(){
        if (singleton == null){
            singleton = new Singleton();
        }
        return singleton;
    }
}

解決線程安全問題

在方法上加synchronized同步鎖或是用同步代碼塊對(duì)類加同步鎖,此種方式雖然解決了多個(gè)實(shí)例對(duì)象問題,但是該方式運(yùn)行效率卻很低下,下一個(gè)線程想要獲取對(duì)象,就必須等待上一個(gè)線程釋放鎖之后,才可以繼續(xù)運(yùn)行。

鎖太大

public class Singleton {
    /**
     * 私有構(gòu)造
     */
    private Singleton(){
        System.out.println("構(gòu)造函數(shù)Singleton");
    }
    private static Singleton singleton = null;
    public static synchronized Singleton getInstance(){
        if (singleton == null){
            singleton = new Singleton();
        }
        return singleton;
    }
}

雙重檢查鎖

提高同步鎖的效率

使用雙重檢查鎖進(jìn)一步做了優(yōu)化,可以避免整個(gè)方法被鎖,只對(duì)需要鎖的代碼部分加鎖,可以提高執(zhí)行效率。

第一個(gè)if判斷

第一個(gè)線程進(jìn)來new了Singleton,那么singleton就有值,第二個(gè)線程進(jìn)來,那么進(jìn)行第一個(gè)if判斷,不為null,直接返回,不用再去new了,提升了效率

第二個(gè)if判斷

兩個(gè)線程同時(shí)進(jìn)來,在synchronized,第一個(gè)線程進(jìn)入,另一個(gè)線程等待,第一個(gè)線程new Singleton,然后返回,另一個(gè)線程發(fā)現(xiàn)了第一個(gè)線程走了,進(jìn)入synchronized,如果不進(jìn)行if判斷,那么還會(huì)new Singleton,導(dǎo)致線程不安全

public class Singleton {
    /**
     * 私有構(gòu)造
     */
    private Singleton(){
        System.out.println("構(gòu)造函數(shù)Singleton");
    }
    private static Singleton singleton = null;
    public static synchronized Singleton getInstance(){
        if (singleton == null){  //這個(gè)檢查是提高效率的
            synchronized (Singleton.class){
                if (singleton == null){
                    singleton = new Singleton();   //這個(gè)檢查是防止線程安全的
                }
            }
        }
        return singleton;
    }
}

靜態(tài)內(nèi)部類

這種方式引入了一個(gè)內(nèi)部靜態(tài)類(static class),靜態(tài)內(nèi)部類只有在調(diào)用時(shí)才會(huì)加載,它保證了Singleton 實(shí)例的延遲初始化,又保證了實(shí)例的唯一性。它把singleton 的實(shí)例化操作放到一個(gè)靜態(tài)內(nèi)部類中,在第一次調(diào)用getInstance() 方法時(shí),JVM才會(huì)去加載InnerObject類,同時(shí)初始化singleton 實(shí)例,所以能讓getInstance() 方法線程安全。

特點(diǎn)是:即能延遲加載,也能保證線程安全。

靜態(tài)內(nèi)部類雖然保證了單例在多線程并發(fā)下的線程安全性,但是在遇到序列化對(duì)象時(shí),默認(rèn)的方式運(yùn)行得到的結(jié)果就是多例的。

public class Singleton {
    /**
     * 私有構(gòu)造
     */
    private Singleton(){
    }
    private static class InnerObject{
        private static Singleton singleton = new Singleton();
    }
    public static synchronized Singleton getInstance(){
        return InnerObject.singleton;
    }
}

內(nèi)部枚舉類實(shí)現(xiàn)

防止反射和反序列化攻擊

實(shí)上,通過Java反射機(jī)制是能夠?qū)嵗瘶?gòu)造方法為private的類的。這也就是我們現(xiàn)在需要引入的枚舉單例模式。

public class SingletonFactory {
    /**
     * 私有構(gòu)造
     */
    private enum EnumSingleton{
        SINGLETON;
        private Singleton6 singleton;
        //枚舉類的構(gòu)造方法在類加載是被實(shí)例化
        private EnumSingleton(){
            singleton = new Singleton6();
        }
        public Singleton6 getInstance(){
            return singleton;
        }
    }
    public static Singleton6 getInstance(){
        return EnumSingleton.SINGLETON.getInstance();
    }
}
class Singleton6{
    public Singleton6(){
    }
}

到此這篇關(guān)于Java實(shí)現(xiàn)單例模式的五種方法介紹的文章就介紹到這了,更多相關(guān)Java單例模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java顯示聲音波形圖示例

    java顯示聲音波形圖示例

    這篇文章主要介紹了java顯示聲音波形圖示例,需要的朋友可以參考下
    2014-05-05
  • JAVA操作MongoDB數(shù)據(jù)庫實(shí)例教程

    JAVA操作MongoDB數(shù)據(jù)庫實(shí)例教程

    MongoDB是一個(gè)文檔型數(shù)據(jù)庫,是NOSQL家族中最重要的成員之一,下面這篇文章主要給大家介紹了關(guān)于JAVA操作MongoDB數(shù)據(jù)庫的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • 利用java監(jiān)聽器實(shí)現(xiàn)在線人數(shù)統(tǒng)計(jì)

    利用java監(jiān)聽器實(shí)現(xiàn)在線人數(shù)統(tǒng)計(jì)

    過去使用ASP和ASP.NET兩種編程的時(shí)候,都寫過在線人數(shù)統(tǒng)計(jì)能,實(shí)現(xiàn)功能挺簡(jiǎn)單的!今天使用java來實(shí)現(xiàn)在線人數(shù)統(tǒng)計(jì)有點(diǎn)另類,是通過Java監(jiān)聽器實(shí)現(xiàn)的,需要的朋友可以參考下
    2015-09-09
  • 四個(gè)Java常見分布式鎖的選型和性能對(duì)比

    四個(gè)Java常見分布式鎖的選型和性能對(duì)比

    當(dāng)涉及到分布式系統(tǒng)中的并發(fā)控制和數(shù)據(jù)一致性時(shí),分布式鎖是一種常見的解決方案,本文將對(duì)幾種常見的分布式鎖實(shí)現(xiàn)原理、實(shí)現(xiàn)示例、應(yīng)用場(chǎng)景以及優(yōu)缺點(diǎn)進(jìn)行詳細(xì)分析,需要的可以參考一下
    2023-05-05
  • Mybatis和Mybatis-Plus時(shí)間范圍查詢方式

    Mybatis和Mybatis-Plus時(shí)間范圍查詢方式

    這篇文章主要介紹了Mybatis和Mybatis-Plus時(shí)間范圍查詢方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Docker?DockerFile部署java?jar項(xiàng)目包及Mysql和Redis的詳細(xì)過程

    Docker?DockerFile部署java?jar項(xiàng)目包及Mysql和Redis的詳細(xì)過程

    Dockerfile是一種用于構(gòu)建Docker鏡像的文件格式,可以通過Dockerfile部署Java項(xiàng)目,這篇文章主要給大家介紹了關(guān)于Docker?DockerFile部署java?jar項(xiàng)目包及Mysql和Redis的詳細(xì)過程,需要的朋友可以參考下
    2023-12-12
  • 詳解使用Spring的BeanPostProcessor優(yōu)雅的實(shí)現(xiàn)工廠模式

    詳解使用Spring的BeanPostProcessor優(yōu)雅的實(shí)現(xiàn)工廠模式

    這篇文章主要介紹了詳解使用Spring的BeanPostProcessor優(yōu)雅的實(shí)現(xiàn)工廠模式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • SpringBoot整合MybatisSQL過濾@Intercepts的實(shí)現(xiàn)

    SpringBoot整合MybatisSQL過濾@Intercepts的實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot整合MybatisSQL過濾@Intercepts的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Java實(shí)現(xiàn)對(duì)華北、華南、華東和華中四個(gè)區(qū)域的劃分

    Java實(shí)現(xiàn)對(duì)華北、華南、華東和華中四個(gè)區(qū)域的劃分

    在Java中,通過定義枚舉類、編寫主程序和進(jìn)行測(cè)試,本文詳細(xì)介紹了如何劃分華北、華南、華東和華中四個(gè)區(qū)域,首先定義枚舉類標(biāo)識(shí)區(qū)域,然后通過主程序接收用戶輸入并返回相應(yīng)區(qū)域,最后通過測(cè)試用例確保正確性,文章還介紹了甘特圖和餅狀圖的使用
    2024-09-09
  • Java序列化和反序列化_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java序列化和反序列化_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    把對(duì)象轉(zhuǎn)換為字節(jié)序列的過程稱為對(duì)象的序列化,把字節(jié)序列恢復(fù)為對(duì)象的過程稱為對(duì)象的反序列化。接下來通過本文給大家介紹Java序列化和反序列化及主要的兩種用途,感興趣的的友參考下吧
    2017-05-05

最新評(píng)論