最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析Java單例設(shè)計(jì)模式(自寫(xiě)demo)

 更新時(shí)間:2021年12月14日 16:01:07   作者:海深不見(jiàn)鯨  
Java單例模式是看起來(lái)以及用起來(lái)簡(jiǎn)單的一種設(shè)計(jì)模式,但是就實(shí)現(xiàn)方式以及原理來(lái)說(shuō),也并不淺顯,下面這篇文章主要給大家詳細(xì)介紹了Java中單例模式,需要的朋友可以參考下

單例模式特點(diǎn)

1、構(gòu)造器私有

2、在一個(gè)Java應(yīng)用程序中,可保證只有一個(gè)實(shí)例對(duì)象

3、只提供一個(gè)供外界調(diào)用的getInstance()方法

單例模式優(yōu)點(diǎn)

1、減少某些對(duì)象的頻繁創(chuàng)建,降低系統(tǒng)開(kāi)銷(xiāo)和內(nèi)存占用

2、外部調(diào)用不使用new關(guān)鍵字,降低系統(tǒng)內(nèi)存的使用頻率

3、對(duì)于特殊的類(lèi),在系統(tǒng)中只能存在一個(gè)實(shí)例,否則系統(tǒng)無(wú)法正常運(yùn)行,比如Controller

實(shí)現(xiàn)方式

這里簡(jiǎn)單介紹兩種實(shí)現(xiàn)方式

餓漢式(線程安全)

/**
 * @author: xuzhilei6656
 * @create: 2021-12-12 12:07
 * @description: 單例模式(餓漢式)
 **/
public class Singleton {
    //創(chuàng)建實(shí)例
    private static Singleton instance = new Singleton();
 
    //私有構(gòu)造器
    private Singleton(){
    }
 
    //獲取實(shí)例的靜態(tài)方法
    public static Singleton getInstance(){
        return instance;
    }
 
}

實(shí)例對(duì)象在類(lèi)被加載的時(shí)候就已經(jīng)完成初始化,外界調(diào)用拿到的都是這個(gè)唯一的實(shí)例對(duì)象

懶漢式

/**
 * @author: xuzhilei6656
 * @create: 2021-12-12 12:22
 * @description: 單例模式(懶漢式)
 **/
public class Singleton {
    //聲明一個(gè)變量
    private static Singleton instance;
 
    //私有構(gòu)造器
    private Singleton(){
    }
 
    //獲取實(shí)例的靜態(tài)方法
    public static Singleton getInstance(){
        //如果是首次調(diào)用,實(shí)例對(duì)象還沒(méi)有被創(chuàng)建,就需要?jiǎng)?chuàng)建,否則都是返回已經(jīng)創(chuàng)建過(guò)的那個(gè)對(duì)象
        if (instance == null){
            instance = new Singleton();
        }
        return instance;
    }
 
}

對(duì)比餓漢式可見(jiàn),實(shí)例對(duì)象在類(lèi)被加載的時(shí)候并沒(méi)有進(jìn)行創(chuàng)建,在首次調(diào)用的時(shí)候才被創(chuàng)建,以后再被調(diào)用,返回的也是那個(gè)唯一的實(shí)例對(duì)象。

在多線程情況下,這種寫(xiě)法存在線程安全問(wèn)題,比如:線程A在執(zhí)行完if判斷條件后進(jìn)入阻塞狀態(tài),此時(shí)并沒(méi)有進(jìn)行對(duì)象創(chuàng)建,此時(shí)線程B來(lái)了,在執(zhí)行完if條件后直接進(jìn)行對(duì)象創(chuàng)建,等線程A恢復(fù)運(yùn)行狀態(tài)后也會(huì)進(jìn)行對(duì)象創(chuàng)建,這個(gè)時(shí)候就不符合單例模式了,即出現(xiàn)了線程不安全的問(wèn)題。

解決方案:在獲取實(shí)例的靜態(tài)方法上加synchronized關(guān)鍵字,即加鎖

/**
 * @author: xuzhilei6656
 * @create: 2021-12-12 12:22
 * @description: 單例模式(懶漢式)
 **/
public class Singleton {
    //聲明一個(gè)變量
    private static Singleton instance;
 
    //私有構(gòu)造器
    private Singleton(){
    }
 
    //獲取實(shí)例的靜態(tài)方法
    public static synchronized Singleton getInstance(){
        //如果是首次調(diào)用,實(shí)例對(duì)象還沒(méi)有被創(chuàng)建,就需要?jiǎng)?chuàng)建,否則都是返回已經(jīng)創(chuàng)建過(guò)的那個(gè)對(duì)象
        if (instance == null){
            instance = new Singleton();
        }
        return instance;
    }
 
}

簡(jiǎn)單粗暴,可達(dá)到我們的目的,但是每次獲取實(shí)例對(duì)象都要有加鎖操作,影響系統(tǒng)性能。

改進(jìn)后的方案:雙重檢查

/**
 * @author: xuzhilei6656
 * @create: 2021-12-12 12:22
 * @description: 單例模式(懶漢式)
 **/
public class Singleton {
    //聲明一個(gè)變量
    private static Singleton instance;
 
    //私有構(gòu)造器
    private Singleton(){
    }
 
    //獲取實(shí)例的靜態(tài)方法
    public static synchronized Singleton getInstance(){
        //第一次檢查
        if (instance == null){
            //獲取鎖
            synchronized (Singleton.class){
                //第二次檢查
                if (instance==null){
                    //兩次檢查都確定沒(méi)有已存在的實(shí)例對(duì)象,這才進(jìn)行對(duì)象的創(chuàng)建操作
                    instance = new Singleton();
                }
            }
            
        }
        return instance;
    }
 
}

這樣不必每次獲取實(shí)例對(duì)象的時(shí)候都進(jìn)行加鎖操作,只有在第一次創(chuàng)建對(duì)象的時(shí)候才進(jìn)行加鎖操作,提高了系統(tǒng)性能。

但是,即使這樣有可能會(huì)出現(xiàn)。因?yàn)?instance = new Singleton()這行代碼在JVM中是兩個(gè)操作,賦值和初始化實(shí)例,但JVM并不保證這兩個(gè)操作的順序,有可能JVM給新對(duì)象分配了空間,直接賦值給instance變量,然后才去做初始化實(shí)例操作。比如下面這種情況

1,A,B兩個(gè)線程都進(jìn)入第一個(gè)if條件

2,A線程先搶到鎖進(jìn)入到synchronized代碼塊,執(zhí)行了instance = new Singleton()這行代碼,然后釋放鎖,此時(shí)有可能JVM只給實(shí)例對(duì)象分配了空白的內(nèi)存空間,并沒(méi)有執(zhí)行初始化操作

3,B線程搶到鎖,進(jìn)入到synchronized代碼塊,第二次判斷的時(shí)候發(fā)現(xiàn)instance不是null,直接返回使用卻發(fā)現(xiàn)得到的對(duì)象還沒(méi)有被初始化,于是出現(xiàn)了問(wèn)題。

再次改進(jìn):使用volatile關(guān)鍵字修飾聲明的成員變量instance

/**
 * @author: xuzhilei6656
 * @create: 2021-12-12 12:22
 * @description: 單例模式(懶漢式)
 **/
public class Singleton {
    //聲明變量,被volatile修飾
    private volatile static Singleton instance;
 
    //私有構(gòu)造器
    private Singleton(){
    }
 
    //獲取實(shí)例的靜態(tài)方法
    public static synchronized Singleton getInstance(){
        //第一次檢查
        if (instance == null){
            //獲取鎖
            synchronized (Singleton.class){
                //第二次檢查
                if (instance==null){
                    //兩次檢查都確定沒(méi)有已存在的實(shí)例對(duì)象,這才進(jìn)行對(duì)象的創(chuàng)建操作
                    instance = new Singleton();
                }
            }
 
        }
        return instance;
    }
 
}

volatile關(guān)鍵字作用:通過(guò)volatile修飾的變量,不會(huì)被線程本地緩存,所有線程對(duì)該對(duì)象的讀寫(xiě)都會(huì)第一時(shí)間同步到主內(nèi)存,從而保證多個(gè)線程間該對(duì)象的準(zhǔn)確性。

這個(gè)寫(xiě)法已經(jīng)比較完美了,既能保證安全的創(chuàng)建出唯一實(shí)例,又不會(huì)對(duì)系統(tǒng)性能有太大影響。

不過(guò),還有更優(yōu)的寫(xiě)法:靜態(tài)內(nèi)部類(lèi)實(shí)現(xiàn)

?
/**
 * @author: xuzhilei6656
 * @create: 2021-12-12 15:17
 * @description: 單例模式
 **/
public class Singleton {
 
    //私有構(gòu)造器
    private Singleton() {
    }
 
    //靜態(tài)內(nèi)部類(lèi)聲明實(shí)例
    private static class SingletonFactory{
        private static Singleton instance = new Singleton();
    }
 
    //獲取實(shí)例的靜態(tài)方法
    public static Singleton getInstance(){
        return SingletonFactory.instance;
    }
    
}
 
?

使用內(nèi)部類(lèi)來(lái)維護(hù)單例的實(shí)現(xiàn),JVM內(nèi)部的機(jī)制能夠保證當(dāng)一個(gè)類(lèi)被加載的時(shí)候,這個(gè)類(lèi)的加載過(guò)程是線程互斥的。這樣當(dāng)我們第一次調(diào)用getInstance()方法的時(shí)候,JVM能夠保證創(chuàng)建出唯一的實(shí)例對(duì)象,并且這個(gè)實(shí)例對(duì)象是已經(jīng)被初始化完成的,就解決了上面的線程安全問(wèn)題

最后一種實(shí)現(xiàn)單例的寫(xiě)法也很完美,代碼最簡(jiǎn)潔

通過(guò)枚舉

/**
 * @author: xuzhilei6656
 * @create: 2021-12-12 15:33
 * @description: 單例模式
 **/
public enum Singleton {
 
    //代表一個(gè)Singleton實(shí)例
    INSTANCE;
}

通過(guò)枚舉來(lái)實(shí)現(xiàn)單實(shí)例代碼更加簡(jiǎn)潔,而且JVM從根本上保證實(shí)例對(duì)象的唯一性,是更簡(jiǎn)潔、高效、安全的實(shí)現(xiàn)單例的方式?

以上就是淺析Java單例設(shè)計(jì)模式(自寫(xiě)demo)的詳細(xì)內(nèi)容,更多關(guān)于Java單例模式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot實(shí)現(xiàn)設(shè)置全局和局部時(shí)間格式化

    SpringBoot實(shí)現(xiàn)設(shè)置全局和局部時(shí)間格式化

    本文主要介紹了SpringBoot實(shí)現(xiàn)設(shè)置全局和局部時(shí)間格式化,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • spring中的@Value讀取配置文件的細(xì)節(jié)處理過(guò)程

    spring中的@Value讀取配置文件的細(xì)節(jié)處理過(guò)程

    這篇文章主要介紹了spring中的@Value讀取配置文件的細(xì)節(jié)處理過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 基于java Springboot實(shí)現(xiàn)教務(wù)管理系統(tǒng)詳解

    基于java Springboot實(shí)現(xiàn)教務(wù)管理系統(tǒng)詳解

    這篇文章主要介紹了Java 實(shí)現(xiàn)簡(jiǎn)易教務(wù)管理系統(tǒng)的代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • java 后臺(tái)將base64字符串保存為圖片的方法

    java 后臺(tái)將base64字符串保存為圖片的方法

    本篇文章主要介紹了java 后臺(tái)將base64字符串保存為圖片的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • SpringBoot項(xiàng)目啟動(dòng)執(zhí)行任務(wù)的多種方法小結(jié)

    SpringBoot項(xiàng)目啟動(dòng)執(zhí)行任務(wù)的多種方法小結(jié)

    這篇文章主要介紹了SpringBoot項(xiàng)目啟動(dòng)執(zhí)行任務(wù)的多種方法小結(jié),本文給大家分享的這幾種方法經(jīng)常會(huì)被用到,當(dāng)我們的項(xiàng)目啟動(dòng)后需要調(diào)用對(duì)應(yīng)的方法,用來(lái)項(xiàng)目的初始化等,本文通過(guò)示例代碼講解的非常詳細(xì),需要的朋友參考下吧
    2023-07-07
  • Java OpenCV利用KNN算法實(shí)現(xiàn)圖像背景移除

    Java OpenCV利用KNN算法實(shí)現(xiàn)圖像背景移除

    這篇文章主要為大家介紹了Java OpenCV利用K最鄰近(KNN,K-NearestNeighbor)分類(lèi)算法實(shí)現(xiàn)圖像背景移除的示例代碼,需要的可以參考一下
    2022-01-01
  • 解決spring @ControllerAdvice處理異常無(wú)法正確匹配自定義異常

    解決spring @ControllerAdvice處理異常無(wú)法正確匹配自定義異常

    這篇文章主要介紹了解決spring @ControllerAdvice處理異常無(wú)法正確匹配自定義異常的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • mybatis-plus 擴(kuò)展批量新增的實(shí)現(xiàn)

    mybatis-plus 擴(kuò)展批量新增的實(shí)現(xiàn)

    本文主要介紹了mybatis-plus 擴(kuò)展批量新增的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • Springboot使用RestTemplate調(diào)用第三方接口的操作代碼

    Springboot使用RestTemplate調(diào)用第三方接口的操作代碼

    這篇文章主要介紹了Springboot使用RestTemplate調(diào)用第三方接口,我只演示了最常使用的請(qǐng)求方式get、post的簡(jiǎn)單使用方法,當(dāng)然RestTemplate的功能還有很多,感興趣的朋友可以參考RestTemplate源碼
    2022-12-12
  • Java Comparator.comparing比較導(dǎo)致空指針異常的解決

    Java Comparator.comparing比較導(dǎo)致空指針異常的解決

    這篇文章主要介紹了Java Comparator.comparing比較導(dǎo)致空指針異常的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07

最新評(píng)論

子洲县| 邻水| 绵阳市| 彭水| 海原县| 陇南市| 兴文县| 仁怀市| 岑巩县| 枝江市| 大埔县| 怀来县| 南江县| 浦江县| 塔城市| 郯城县| 浏阳市| 赤壁市| 莱州市| 陇南市| 民县| 霍林郭勒市| 苏尼特左旗| 扶绥县| 洛隆县| 义马市| 西宁市| 满洲里市| 盐亭县| 白银市| 雷山县| 乌审旗| 江西省| 灵武市| 保靖县| 临沧市| 车致| 邵东县| 鲁甸县| 宣武区| 铁岭市|