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

Java?設(shè)計(jì)模式以虹貓藍(lán)兔的故事講解單例模式

 更新時(shí)間:2022年03月28日 17:27:53   作者:桃花鍵神  
單例模式(Singleton?Pattern)是?Java?中最簡(jiǎn)單的設(shè)計(jì)模式之一。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式

專欄介紹

【JAVA長(zhǎng)虹鍵法】 主要講了23種設(shè)計(jì)模式,本系列專欄會(huì)以虹貓藍(lán)兔七俠傳的故事為例來(lái)給大家詳細(xì)分析所有模式,希望能給大家?guī)?lái)幫助!

本期介紹

模式: 單例模式

案例: 虹貓藍(lán)兔造劍

什么是單例模式

單例模式(Singleton Pattern)是 Java 中最簡(jiǎn)單的設(shè)計(jì)模式之一。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式。 這種模式涉及到一個(gè)單一的類,該類負(fù)責(zé)創(chuàng)建自己的對(duì)象,同時(shí)確保只有單個(gè)對(duì)象被創(chuàng)建。這個(gè)類提供了一種訪問(wèn)其唯一的對(duì)象的方式,可以直接訪問(wèn),不需要實(shí)例化該類的對(duì)象。

注意:

1、單例類只能有一個(gè)實(shí)例。

2、單例類必須自己創(chuàng)建自己的唯一實(shí)例。

3、單例類必須給所有其他對(duì)象提供這一實(shí)例。

單例模式大致分為懶漢式和餓漢式,接下來(lái)用案例分析

懶漢式一

是否 Lazy 初始化: 是

是否多線程安全:否

實(shí)現(xiàn)難度: 易

描述: 這種方式是最基本的實(shí)現(xiàn)方式,這種實(shí)現(xiàn)最大的問(wèn)題就是不支持多線程。因?yàn)闆]有加鎖 synchronized,所以嚴(yán)格意義上它并不算單例模式。

這種方式 lazy loading 很明顯,不要求線程安全,在多線程不能正常工作。

概念看不懂沒關(guān)系,接下來(lái)舉例。

案例一:

創(chuàng)建一個(gè)劍類,這個(gè)類可以實(shí)例化一把劍。

虹貓和藍(lán)兔兩個(gè)人都想要造一把劍,虹貓先打造了一把劍,命名為長(zhǎng)虹劍,然后藍(lán)兔也打造了一把劍,但是沒有命名。

現(xiàn)在來(lái)分析兩個(gè)情況,一個(gè)情況是正常模式,另一種情況是單例模式。

正常模式

劍類:

public class Jians {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

測(cè)試類:

public class Demo1 {
    public static void main(String[] args) {
         //虹貓的劍
        Jians hong = new Jians();
         //藍(lán)兔的劍
        Jians lan = new Jians();
        hong.setName("長(zhǎng)虹劍");
        System.out.println(hong.getName());
        System.out.println(lan.getName());
    }
}

結(jié)果:

在正常模式下,我new了虹貓和藍(lán)兔的劍。其實(shí)就是兩把劍,兩個(gè)不同的對(duì)象。

單例模式

劍類:

劍類中的getInstance()方法有一個(gè)造劍的功能,也就是new一個(gè)劍對(duì)象的功能。

 public class Jian {
    private static Jian jian;
    private String name;

    public static Jian getInstance() {
        if (jian == null) {
            jian = new Jian();
        }
        return jian;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

測(cè)試類:

public class Demo {
    public static void main(String[] args) {
        //虹貓的劍
        Jian hong = Jian.getInstance();
        //藍(lán)兔的劍
        Jian lan = Jian.getInstance();
        //虹貓把劍命名長(zhǎng)虹劍
        hong.setName("長(zhǎng)虹劍");
        //輸出
        System.out.println(hong.getName());
        System.out.println(lan.getName());
    }
}

結(jié)果:

在單例模式下,我new了虹貓和藍(lán)兔的劍。其實(shí)就是一把劍,一個(gè)相同的對(duì)象。

為什么線程不安全呢

單例模式下的劍類:

 public class Jian {
    private static Jian jian;
    private String name;

    public static Jian getInstance() {
        if (jian == null) {
            jian = new Jian();
        }
        return jian;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

就拿這個(gè)類來(lái)說(shuō),他是線程不安全的。因?yàn)樗ㄟ^(guò)getInstance()方法來(lái)獲取對(duì)象。如果是多線程運(yùn)行,有線程1和線程2都先后進(jìn)入了這個(gè)方法,因?yàn)榫€程1剛進(jìn)入方法還沒有返回對(duì)象,線程2就進(jìn)入了方法。所以線程2也會(huì)new一個(gè)對(duì)象,因?yàn)榇藭r(shí)線程2進(jìn)入方法的時(shí)候jian還是null的。

懶漢式二

是否 Lazy 初始化: 是

是否多線程安全: 是

實(shí)現(xiàn)難度: 易

描述: 這種方式具備很好的 lazy loading,能夠在多線程中很好的工作,但是,效率很低,99% 情況下不需要同步。

優(yōu)點(diǎn): 第一次調(diào)用才初始化,避免內(nèi)存浪費(fèi)。

缺點(diǎn): 必須加鎖 synchronized 才能保證單例,但加鎖會(huì)影響效率。

為什么線程安全呢

這里還用上面那個(gè)案例,這次主要介紹懶漢式一和懶漢式二的區(qū)別。

懶漢式一和懶漢式二的主要區(qū)別在劍類上。

懶漢式一的劍類:

 public class Jian {
    private static Jian jian;
    private String name;

    public static Jian getInstance() {
        if (jian == null) {
            jian = new Jian();
        }
        return jian;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

懶漢式二的劍類:

 public class Jian {
    private static Jian jian;
    private String name;

    public static synchronized Jian getInstance() {
        if (jian == null) {
            jian = new Jian();
        }
        return jian;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

在getInstance()方法前加了個(gè)字段synchronized,synchronized是一把鎖,作用是同一時(shí)間只能有一個(gè)線程進(jìn)入這個(gè)方法,這樣就避免了懶漢式一中兩個(gè)線程都進(jìn)入方法的情況出現(xiàn),就不會(huì)new兩個(gè)對(duì)象,所以線程安全。

餓漢式

是否 Lazy 初始化: 否

是否多線程安全: 是

實(shí)現(xiàn)難度: 易

描述: 這種方式比較常用,但容易產(chǎn)生垃圾對(duì)象。

優(yōu)點(diǎn): 沒有加鎖,執(zhí)行效率會(huì)提高。

缺點(diǎn): 類加載時(shí)就初始化,浪費(fèi)內(nèi)存。

餓漢式就是直接在類中new一個(gè)對(duì)象,就是不管你需不需要?jiǎng)ξ乙呀?jīng)把劍造好了。

餓漢式劍類:

public class Jian {
    private static Jian jian=new Jian();
    private String name;

    public static synchronized Jian getInstance() {
        return jian;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

測(cè)試類:

public class Demo {
    public static void main(String[] args) {
        //虹貓的劍
        Jian hong = Jian.getInstance();
        //藍(lán)兔的劍
        Jian lan = Jian.getInstance();
        //虹貓把劍命名長(zhǎng)虹劍
        hong.setName("長(zhǎng)虹劍");
        //輸出
        System.out.println(hong.getName());
        System.out.println(lan.getName());
    }
}

餓漢式中劍類的getInstance()方法已經(jīng)失去了造劍的功能,測(cè)試類調(diào)用它只是返回一把提前造好的劍

懶漢式與餓漢式的區(qū)別

還是這個(gè)案例,虹貓和藍(lán)兔都想造一把劍,懶漢式是有一個(gè)劍類,劍類中有一個(gè)造劍的方法,調(diào)用這個(gè)方法的時(shí)候打造一把劍。餓漢式也有一個(gè)劍類,不同的是這個(gè)劍類直接就把劍造好了,沒有造劍的方法,不管你虹貓和藍(lán)兔想不想造劍,劍都已經(jīng)造好了。

優(yōu)點(diǎn): 沒有加鎖,執(zhí)行效率會(huì)提高。

缺點(diǎn): 類加載時(shí)就初始化,浪費(fèi)內(nèi)存。

現(xiàn)在在看餓漢式的優(yōu)缺點(diǎn)就容易理解了。

下期預(yù)告

模式: 簡(jiǎn)單工廠模式

案例: 虹貓藍(lán)兔莎莉找鑄劍師造劍

到此這篇關(guān)于Java 設(shè)計(jì)模式以虹貓藍(lán)兔的故事講解單例模式的文章就介紹到這了,更多相關(guān)Java 單例模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • IDEA+Maven創(chuàng)建Spring項(xiàng)目的實(shí)現(xiàn)步驟

    IDEA+Maven創(chuàng)建Spring項(xiàng)目的實(shí)現(xiàn)步驟

    這篇文章主要介紹了IDEA+Maven創(chuàng)建Spring項(xiàng)目的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Gradle的基本使用

    Gradle的基本使用

    這篇文章主要介紹了Gradle的基本使用方法,幫助大家更好的理解和學(xué)習(xí)Gradle的相關(guān)知識(shí),感興趣的朋友可以了解下
    2021-03-03
  • 關(guān)于Eureka的概念作用以及用法詳解

    關(guān)于Eureka的概念作用以及用法詳解

    這篇文章主要介紹了關(guān)于Eureka的概念作用以及用法詳解,服務(wù)治理就是提供了微服務(wù)架構(gòu)中各微服務(wù)實(shí)例的快速上線或下線且保持各服務(wù)能正常通信的能力的方案總稱,需要的朋友可以參考下
    2023-05-05
  • 使用SpringCache進(jìn)行緩存數(shù)據(jù)庫(kù)查詢方式

    使用SpringCache進(jìn)行緩存數(shù)據(jù)庫(kù)查詢方式

    這篇文章主要介紹了使用SpringCache進(jìn)行緩存數(shù)據(jù)庫(kù)查詢方式,具有很好的參考價(jià)值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java回調(diào)機(jī)制解讀

    Java回調(diào)機(jī)制解讀

    本文主要介紹了Java回調(diào)機(jī)制的相關(guān)知識(shí),具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-02-02
  • Java并發(fā)容器ConcurrentLinkedQueue解析

    Java并發(fā)容器ConcurrentLinkedQueue解析

    這篇文章主要介紹了Java并發(fā)容器ConcurrentLinkedQueue解析,
    2023-12-12
  • Spring中的依賴注入DI詳解

    Spring中的依賴注入DI詳解

    這篇文章主要介紹了Spring中的依賴注入DI詳解,組件之間依賴關(guān)系由容器在運(yùn)行期決定,形象的說(shuō),即由容器動(dòng)態(tài)的將依賴關(guān)系注入到組件之中,依賴注入的目的并非為軟件系統(tǒng)帶來(lái)更多功能,是為了提升組件重用的頻率,并為系統(tǒng)搭建一個(gè)靈活、可擴(kuò)展的平臺(tái),需要的朋友可以參考下
    2024-01-01
  • Storm框架整合springboot的方法

    Storm框架整合springboot的方法

    Storm框架中的每個(gè)Spout和Bolt都相當(dāng)于獨(dú)立的應(yīng)用,Strom在啟動(dòng)spout和bolt時(shí)提供了一個(gè)open方法(spout)和prepare方法(bolt)。這篇文章主要介紹了Storm框架整合springboot的方法,需要的朋友可以參考下
    2018-11-11
  • Springboot使用Spring Data JPA實(shí)現(xiàn)數(shù)據(jù)庫(kù)操作

    Springboot使用Spring Data JPA實(shí)現(xiàn)數(shù)據(jù)庫(kù)操作

    Spring Data JPA 是 Spring 基于 Spring Data 框架、在JPA 規(guī)范的基礎(chǔ)上開發(fā)的一個(gè)框架,使用 Spring Data JPA 可以極大地簡(jiǎn)化JPA 的寫法,本章我們將詳細(xì)介紹在Springboot中使用 Spring Data JPA 來(lái)實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的操作
    2021-06-06
  • Spring5學(xué)習(xí)之基礎(chǔ)知識(shí)總結(jié)

    Spring5學(xué)習(xí)之基礎(chǔ)知識(shí)總結(jié)

    這篇文章主要介紹了Spring5學(xué)習(xí)之基礎(chǔ)知識(shí)總結(jié),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-05-05

最新評(píng)論