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

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

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

單例模式

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

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

餓漢式單例模式

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

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

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

優(yōu)點:

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

缺點:

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

懶漢式單例模式

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

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

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

優(yōu)點:

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

缺點:

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

雙重校驗鎖單例模式

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

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;
    }
}

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

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

優(yōu)點:

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

缺點:

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

枚舉單例模式

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

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

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

優(yōu)點:

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

缺點:

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

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

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

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

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

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

優(yōu)點:

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

缺點:

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

注冊式單例模式

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

下面是一個使用 ConcurrentHashMap 實現(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 注冊機制使用的是注冊式單例模式。在 Spring 中, Bean 的注冊是通過 BeanDefinitionRegistry 接口來完成的,而 BeanDefinitionRegistry 接口的實現(xiàn)類包括了 DefaultListableBeanFactoryGenericApplicationContext 等。這些實現(xiàn)類在內(nèi)部都使用了類似于注冊式單例模式的方式來注冊和管理 Bean 。

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

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

優(yōu)點:

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

缺點:

  • 容易造成內(nèi)存泄漏,因為單例實例不會被釋放。
  • 可能會造成重復(fù)創(chuàng)建對象的問題。

ThreadLocal單例模式

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

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();
    }
}

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

優(yōu)點:

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

缺點:

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

CAS單例模式

CAS單例模式這種實現(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);
    }
}

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

優(yōu)點:

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

缺點:

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

總結(jié)

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

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

相關(guān)文章

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

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

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

    python?unicodedata模塊用法

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

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

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

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

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

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

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

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

    這篇文章主要介紹了Pycharm激活方法及詳細(xì)教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    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ǔ)語言的難點和技巧,分享給大家。
    2017-11-11
  • python實現(xiàn)b站直播自動發(fā)送彈幕功能

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

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

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

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

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

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

最新評論

洞头县| 炎陵县| 祁阳县| 天津市| 合水县| 宁陕县| 亳州市| 凤翔县| 海淀区| 汝城县| 响水县| 江孜县| 永嘉县| 泊头市| 武宣县| 林西县| 米易县| 台中市| 钟山县| 大关县| 汪清县| 上犹县| 山东省| 宝丰县| 郯城县| 额尔古纳市| 什邡市| 嘉黎县| 剑川县| 固始县| 视频| 册亨县| 富锦市| 辽阳市| 工布江达县| 资源县| 利辛县| 格尔木市| 阳朔县| 乌兰察布市| 美姑县|