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

Java中的各種單例模式優(yōu)缺點(diǎn)解析

 更新時(shí)間:2023年07月06日 08:47:22   作者:索碼理  
這篇文章主要介紹了Java中的各種單例模式解析,單例模式是Java中最簡單的設(shè)計(jì)模式之一,這種類型的設(shè)計(jì)模式屬于創(chuàng)建者模式,它提供了一種訪問對象的最佳方式,需要的朋友可以參考下

單例模式

單例模式是一種創(chuàng)建型設(shè)計(jì)模式,其目的是確保類只有一個(gè)實(shí)例,并且提供全局訪問點(diǎn)以訪問該實(shí)例。

在 Java 中,實(shí)現(xiàn)單例模式有多種方式,下面介紹其中的一些。

餓漢式單例模式

在餓漢式單例模式中,實(shí)例在類加載時(shí)就被創(chuàng)建,因此可以保證實(shí)例的唯一性。該模式的實(shí)現(xiàn)非常簡單,可以使用靜態(tài)初始化器或者私有構(gòu)造方法來實(shí)現(xiàn)。例如:

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

在這個(gè)例子中, INSTANCE 是一個(gè)靜態(tài)常量,它在類加載時(shí)被初始化為 Singleton 類的實(shí)例。getInstance() 方法提供了對該實(shí)例的全局訪問點(diǎn)。

優(yōu)點(diǎn):

  • 線程安全,因?yàn)閷?shí)例在類加載的時(shí)候就已經(jīng)創(chuàng)建好了。
  • 簡單易用,沒有線程同步等復(fù)雜問題。
  • 線程訪問單例實(shí)例的速度比懶漢式單例模式更快。

缺點(diǎn):

  • 類加載時(shí)就創(chuàng)建實(shí)例,有可能會(huì)浪費(fèi)資源。
  • 如果單例類依賴于其他類,這些依賴的類在類加載時(shí)也會(huì)被創(chuàng)建,

懶漢式單例模式

在懶漢式單例模式中,實(shí)例在第一次使用時(shí)才被創(chuàng)建。

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

在上面的實(shí)現(xiàn)中,instance 是靜態(tài)變量,用于存儲(chǔ)單例對象。在 getInstance 方法中,如果 instance 為 null,則創(chuàng)建一個(gè)新的 Singleton 對象,否則直接返回 instance。由于沒有進(jìn)行同步鎖定,所以線程不安全,可能會(huì)導(dǎo)致并發(fā)創(chuàng)建多個(gè)實(shí)例的問題。

優(yōu)點(diǎn):

  • 延遲對象的創(chuàng)建時(shí)間,減少內(nèi)存占用。
  • 簡單易懂,易于實(shí)現(xiàn)。

缺點(diǎn):

  • 非線程安全,需要考慮并發(fā)情況。
  • 多線程環(huán)境下,需要使用同步鎖或者雙重校驗(yàn)鎖來保證線程安全,可能會(huì)影響性能。

雙重校驗(yàn)鎖單例模式

“雙重檢查鎖”(Double-Checked Locking) 是懶漢式的一種優(yōu)化,這種實(shí)現(xiàn)方式結(jié)合了懶漢式和餓漢式的優(yōu)點(diǎn),既能夠延遲對象的創(chuàng)建時(shí)間,又能夠保證線程安全。

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

在這個(gè)例子中, INSTANCE 是一個(gè) volatile 的靜態(tài)變量,它在第一次使用時(shí)被創(chuàng)建。getInstance() 方法使用雙重檢查鎖定來確保 INSTANCE 的唯一性。當(dāng)多個(gè)線程同時(shí)訪問 getInstance() 方法時(shí),只有第一個(gè)線程會(huì)獲得鎖定并創(chuàng)建實(shí)例。其他線程會(huì)等待鎖定被釋放后再次檢查 INSTANCE 是否為空,從而避免了多次創(chuàng)建實(shí)例的情況。

需要注意的是,使用 volatile 關(guān)鍵字可以確保 INSTANCE 變量的可見性和有序性,從而保證多線程環(huán)境下的正確性。

優(yōu)點(diǎn):

  • 延遲加載,只有當(dāng)需要用到實(shí)例時(shí)才會(huì)創(chuàng)建,節(jié)省了系統(tǒng)資源。
  • 線程安全,適合高并發(fā)場景。

缺點(diǎn):

  • 實(shí)現(xiàn)復(fù)雜,容易出現(xiàn)問題。
  • 由于 Java 內(nèi)存模型的限制,可能會(huì)出現(xiàn)指令重排的問題,需要使用 volatile 關(guān)鍵字來解決。

枚舉單例模式

枚舉單例模式是一種比較新的單例模式實(shí)現(xiàn)方式,它在 Java 5 中引入。它利用了 Java 中枚舉類型的特性來實(shí)現(xiàn)單例模式,枚舉類型的每個(gè)枚舉常量都是單例的。

public enum Singleton {
    INSTANCE;
    public void doSomething() {
        // do something...
    }
}

在這個(gè)例子中,枚舉類型 Singleton 只有一個(gè)枚舉常量 INSTANCE ,該常量在枚舉類型初始化時(shí)被創(chuàng)建。由于枚舉類型的實(shí)例在 Java 虛擬機(jī)中是唯一的,因此枚舉常量也是單例的。我們可以通過 Singleton.INSTANCE 來訪問該實(shí)例,并調(diào)用 doSomething() 方法。

優(yōu)點(diǎn):

  • 簡單明了: 枚舉單例模式的實(shí)現(xiàn)非常簡單,而且可以保證線程安全和實(shí)例的唯一性。
  • 序列化安全: 由于枚舉實(shí)例在 JVM 中是唯一的,因此可以保證序列化和反序列化的安全性。
  • 防止反射攻擊: 枚舉實(shí)例在 JVM 中是唯一的,因此可以避免反射攻擊。

缺點(diǎn):

  • 不支持延遲加載 ,因?yàn)槊杜e類型的實(shí)例在類加載時(shí)就已經(jīng)被創(chuàng)建了。
  • 不能繼承其他類 ,因?yàn)槊杜e類型默認(rèn)繼承了Enum類。

靜態(tài)內(nèi)部類單例模式

靜態(tài)內(nèi)部類單例模式是一種優(yōu)雅而簡潔的實(shí)現(xiàn)方式。它利用了 Java 類加載器的機(jī)制來保證實(shí)例的唯一性,并避免了餓漢式單例模式的缺點(diǎn)。

public class Singleton {
    private Singleton() {}
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

在這個(gè)例子中, Singleton 類的構(gòu)造方法是私有的,只能在 Singleton 類的內(nèi)部進(jìn)行調(diào)用。 SingletonHolder 類是 Singleton 類的一個(gè)靜態(tài)內(nèi)部類,它在 Singleton 類被加載時(shí)并不會(huì)立即被加載,而是在第一次調(diào)用 Singleton.getInstance() 方法時(shí)才會(huì)被加載,從而實(shí)現(xiàn)了延遲加載。

由于靜態(tài)內(nèi)部類 SingletonHolder 只會(huì)被加載一次,因此 INSTANCE 實(shí)例也只會(huì)被創(chuàng)建一次,從而保證了實(shí)例的唯一性。總的來說,靜態(tài)內(nèi)部類單例模式是一種比較優(yōu)秀的單例模式實(shí)現(xiàn)方式,它兼顧了線程安全、懶加載和高效等特點(diǎn),是一種值得推薦的單例模式實(shí)現(xiàn)方式。

優(yōu)點(diǎn):

  • 線程安全: 靜態(tài)內(nèi)部類只會(huì)被加載一次,因此可以保證單例對象的線程安全性;
  • 懶加載:靜態(tài)內(nèi)部類只有在被調(diào)用時(shí)才會(huì)被加載,從而實(shí)現(xiàn)了懶加載的效果;
  • 高效:靜態(tài)內(nèi)部類單例模式?jīng)]有加鎖,所以性能比懶漢式和餓漢式都要高;
  • 簡單: 靜態(tài)內(nèi)部類單例模式的實(shí)現(xiàn)比較簡單,代碼量較少。

缺點(diǎn):

  • 不易理解: 相比于餓漢式和懶漢式,靜態(tài)內(nèi)部類單例模式的實(shí)現(xiàn)方式可能不太容易理解;
  • 無法傳遞參數(shù): 靜態(tài)內(nèi)部類單例模式的構(gòu)造函數(shù)是私有的,無法傳遞參數(shù)。如果需要傳遞參數(shù),需要使用其他方式實(shí)現(xiàn)。

注冊式單例模式

注冊式單例模式是一種靈活而可擴(kuò)展的實(shí)現(xiàn)方式。在該模式中,單例實(shí)例被注冊到一個(gè)全局的注冊表中,可以實(shí)現(xiàn)對象的統(tǒng)一管理和獲取,但需要注意容器的生命周期和線程安全問題。

下面是一個(gè)使用 ConcurrentHashMap 實(shí)現(xiàn)注冊式單例模式的例子:

public class Singleton {
    private static Map<String, Singleton> instances = new ConcurrentHashMap<>();
    static {
        instances.put(Singleton.class.getName(), new Singleton());
    }
    private Singleton() {}
    public static Singleton getInstance() {
        return instances.get(Singleton.class.getName());
    }
    public static void register(String key, Singleton instance) {
        instances.put(key, instance);
    }
    public static Singleton getRegisteredInstance(String key) {
        return instances.get(key);
    }
}

Spring 框架中的 Bean 注冊機(jī)制使用的是注冊式單例模式。在 Spring 中, Bean 的注冊是通過 BeanDefinitionRegistry 接口來完成的,而 BeanDefinitionRegistry 接口的實(shí)現(xiàn)類包括了 DefaultListableBeanFactoryGenericApplicationContext 等。這些實(shí)現(xiàn)類在內(nèi)部都使用了類似于注冊式單例模式的方式來注冊和管理 Bean 。

具體來說, Spring 在注冊 Bean 時(shí),會(huì)將 Bean 的定義信息封裝成一個(gè) BeanDefinition 對象,并將其注冊到一個(gè)全局的 BeanFactory 中,以供后續(xù)的使用。在注冊 Bean 的過程中, Spring 會(huì)根據(jù) BeanDefinition 中的配置信息來創(chuàng)建相應(yīng)的 Bean 實(shí)例,同時(shí)還會(huì)對其進(jìn)行依賴注入、生命周期管理等操作。

需要注意的是,SpringBean 注冊機(jī)制中,雖然使用了類似于注冊式單例模式的方式來管理 Bean ,但它并不是一個(gè)完全的單例模式實(shí)現(xiàn)。在 Spring 中, Bean 的單例性是在運(yùn)行時(shí)動(dòng)態(tài)實(shí)現(xiàn)的,而不是在編譯期就確定的。也就是說,如果在 BeanDefinition 中將 scope 屬性設(shè)置為 prototype ,那么每次獲取該 Bean 實(shí)例時(shí)都會(huì)創(chuàng)建一個(gè)新的對象,而不是返回同一個(gè)單例實(shí)例。

優(yōu)點(diǎn):

  • 可以管理多個(gè)單例實(shí)例,可以通過名稱或者其他方式來獲取實(shí)例。
  • 避免了全局變量帶來的問題,比如命名沖突、不同作用域訪問困難等。

缺點(diǎn):

  • 容易造成內(nèi)存泄漏,因?yàn)閱卫龑?shí)例不會(huì)被釋放。
  • 可能會(huì)造成重復(fù)創(chuàng)建對象的問題。

ThreadLocal單例模式

ThreadLocal單例模式這種實(shí)現(xiàn)方式將單例對象存儲(chǔ)在ThreadLocal中,每個(gè)線程都有自己的單例對象副本,保證了線程安全。

public class Singleton {
    private static final ThreadLocal<Singleton> singletonThreadLocal = 
        new ThreadLocal<Singleton>() {
            @Override
            protected Singleton initialValue() {
                return new Singleton();
            }
        };
    private Singleton() {}
    public static Singleton getInstance() {
        return singletonThreadLocal.get();
    }
}

在這個(gè)示例中,每個(gè)線程都有自己的 Singleton 對象副本,使用 ThreadLocal 可以避免線程安全問題。

優(yōu)點(diǎn):

  • 每個(gè)線程都有自己的單例對象副本,線程安全。
  • 可以避免鎖競爭,提高性能。

缺點(diǎn):

  • 可能會(huì)導(dǎo)致內(nèi)存泄漏問題,需要注意對象的生命周期。

CAS單例模式

CAS單例模式這種實(shí)現(xiàn)方式利用了CAS原子操作的特性,可以保證線程安全,但需要注意性能問題。

public class Singleton {
    private static volatile Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    Singleton temp = new Singleton();
                    if (compareAndSetInstance(null, temp)) {
                        instance = temp;
                    }
                }
            }
        }
        return instance;
    }
    private static boolean compareAndSetInstance(Singleton expect, Singleton update) {
        return Unsafe.getUnsafe().compareAndSwapObject(Singleton.class, 
            Unsafe.objectFieldOffset(Singleton.class, "instance"), expect, update);
    }
}

在這個(gè)示例中,使用了 volatileCAS 原子操作來保證線程安全,同時(shí)實(shí)現(xiàn)了懶加載。需要注意的是,使用 Unsafe 類需要特殊權(quán)限,并且 CAS 實(shí)現(xiàn)的復(fù)雜度比較高,適用于高并發(fā)場景。

優(yōu)點(diǎn):

  • 線程安全,高并發(fā)場景性能較好。

缺點(diǎn):

  • 實(shí)現(xiàn)復(fù)雜,需要理解 CAS 原子操作。
  • 需要使用 Unsafe 類,需要特殊權(quán)限。
  • 適用于高并發(fā)場景,對于低并發(fā)場景可能沒有明顯的性能優(yōu)勢。

總結(jié)

總之,單例模式是一種非常常用的設(shè)計(jì)模式,可以確保類只有一個(gè)實(shí)例,并提供全局訪問點(diǎn)以訪問該實(shí)例。在 Java 中,有多種方式可以實(shí)現(xiàn)單例模式,開發(fā)者可以根據(jù)實(shí)際需要選擇適合自己的實(shí)現(xiàn)方式。

到此這篇關(guān)于Java中的各種單例模式優(yōu)缺點(diǎn)解析的文章就介紹到這了,更多相關(guān)Java單例模式解析內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 用python打包exe應(yīng)用程序及PyInstaller安裝方式

    用python打包exe應(yīng)用程序及PyInstaller安裝方式

    PyInstaller 制作出來的執(zhí)行文件并不是跨平臺的,如果需要為不同平臺打包,就要在相應(yīng)平臺上運(yùn)行PyInstaller進(jìn)行打包。今天通過本文給大家介紹用python打包exe應(yīng)用程序及PyInstaller安裝方式,感興趣的朋友一起看看吧
    2021-12-12
  • python?unicodedata模塊用法

    python?unicodedata模塊用法

    這篇文章主要為大家介紹了python?unicodedata模塊用法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 如何用Python畫一些簡單形狀你知道嗎

    如何用Python畫一些簡單形狀你知道嗎

    這篇文章主要介紹了用Python作圖的一個(gè)簡單實(shí)例,通過turtle模塊實(shí)現(xiàn)作圖,具有一定參考價(jià)值,需要的朋友可以了解下希望能給你帶來幫助
    2021-08-08
  • 使用Python實(shí)現(xiàn)將PDF轉(zhuǎn)為圖片

    使用Python實(shí)現(xiàn)將PDF轉(zhuǎn)為圖片

    這篇文章主要為大家詳細(xì)介紹了python如何借用第三方庫Spire.PDF for Python,從而實(shí)現(xiàn)將PDF轉(zhuǎn)為圖片的功能,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-10-10
  • Python連接mysql方法及常用參數(shù)

    Python連接mysql方法及常用參數(shù)

    這篇文章主要介紹了Python連接mysql方法及常用參數(shù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Pycharm激活方法及詳細(xì)教程(詳細(xì)且實(shí)用)

    Pycharm激活方法及詳細(xì)教程(詳細(xì)且實(shí)用)

    這篇文章主要介紹了Pycharm激活方法及詳細(xì)教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2020-05-05
  • Python基礎(chǔ)語言學(xué)習(xí)筆記總結(jié)(精華)

    Python基礎(chǔ)語言學(xué)習(xí)筆記總結(jié)(精華)

    給大家分享一篇關(guān)于Python基礎(chǔ)學(xué)習(xí)內(nèi)容的學(xué)習(xí)筆記整理總結(jié)篇,里面匯集了學(xué)習(xí)Python基礎(chǔ)語言的難點(diǎn)和技巧,分享給大家。
    2017-11-11
  • python實(shí)現(xiàn)b站直播自動(dòng)發(fā)送彈幕功能

    python實(shí)現(xiàn)b站直播自動(dòng)發(fā)送彈幕功能

    這篇文章主要介紹了python如何實(shí)現(xiàn)b站直播自動(dòng)發(fā)送彈幕,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下
    2021-02-02
  • 應(yīng)用OpenCV和Python進(jìn)行SIFT算法的實(shí)現(xiàn)詳解

    應(yīng)用OpenCV和Python進(jìn)行SIFT算法的實(shí)現(xiàn)詳解

    這篇文章主要介紹了應(yīng)用OpenCV和Python進(jìn)行SIFT算法的實(shí)現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Python scrapy爬取起點(diǎn)中文網(wǎng)小說榜單

    Python scrapy爬取起點(diǎn)中文網(wǎng)小說榜單

    爬蟲的基礎(chǔ)內(nèi)容已經(jīng)全部學(xué)玩,博主決定想著更加標(biāo)準(zhǔn)化以及實(shí)用能力更強(qiáng)的scrapy進(jìn)發(fā),今天記錄自己第一個(gè)scrapy爬蟲項(xiàng)目. scrapy爬取起點(diǎn)中文網(wǎng)24小時(shí)熱銷榜單,需要的朋友可以參考下
    2021-06-06

最新評論

清镇市| 乌苏市| 滁州市| 白银市| 南昌县| 鸡西市| 绥中县| 裕民县| 江口县| 永顺县| 秭归县| 高邮市| 阜城县| 克拉玛依市| 安徽省| 繁峙县| 措美县| 秭归县| 新晃| 乌兰县| 团风县| 安丘市| 乌拉特中旗| 贡山| 孟州市| 霍州市| 邵阳市| 中宁县| 昆山市| 新龙县| 长汀县| 乐至县| 香河县| 苍溪县| 博湖县| 江源县| 中方县| 福泉市| 江孜县| 察隅县| 英吉沙县|