国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

單例模式的八種寫法、單例和并發(fā)的關(guān)系

這篇具有很好參考價(jià)值的文章主要介紹了單例模式的八種寫法、單例和并發(fā)的關(guān)系。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1.單例模式的作用

為什么需要單例?

  • 節(jié)省內(nèi)存和計(jì)算
  • 保證結(jié)果正確
  • 方便管理

2.單例模式的適用場景

  1. 無狀態(tài)的工具類:比如日志工具類,不管是在哪里使用,我們需要的只是它幫我們記錄日志信息,除此之外,并不需要在它的實(shí)例對(duì)象上存儲(chǔ)任何狀態(tài),這時(shí)候我們就只需要一個(gè)實(shí)例對(duì)象即可。
  2. 全局信息類:比如我們?cè)谝粋€(gè)類上記錄網(wǎng)站的訪問次數(shù),我們不希望有的訪問被記錄在對(duì)象 A 上,有的卻記錄在對(duì)象 B 上,這時(shí)候我們就讓這個(gè)類成為單例。

3.餓漢式

靜態(tài)常量(可用)

/**
 * 餓漢式(靜態(tài)常量)(可用)
 */
public class Singleton1 {

    // 由于加了static關(guān)鍵字,根據(jù)JVM的規(guī)定,在類加載的時(shí)候就會(huì)完成INSTANCE的實(shí)例化,這樣就避免了線程同步問題
    private final static Singleton1 INSTANCE = new Singleton1();

    // 構(gòu)造函數(shù)是私有的
    private Singleton1() {

    }

    public static Singleton1 getInstance() {
        return INSTANCE;
    }
}

靜態(tài)代碼塊(可用)

/**
 * 餓漢式(靜態(tài)代碼塊)(可用)
 */
public class Singleton2 {

    private final static Singleton2 INSTANCE;

    // 與上一種寫法類似,由JVM保證了線程安全
    static {
        INSTANCE = new Singleton2();
    }

    // 構(gòu)造函數(shù)是私有的
    private Singleton2() {

    }

    public static Singleton2 getInstance() {
        return INSTANCE;
    }
}

4.懶漢式

線程不安全(不可用)

/**
 * 懶漢式(線程不安全)(不可用)
 */
public class Singleton3 {

    private static Singleton3 instance;

    // 構(gòu)造函數(shù)是私有的
    private Singleton3() {

    }

    public static Singleton3 getInstance() {
        // 這種寫法是線程不安全的,不可用
        if (instance == null) {
            instance = new Singleton3();
        }
        return instance;
    }
}

同步方法(線程安全,但不推薦用)

/**
 * 懶漢式(線程安全)(不推薦用)
 */
public class Singleton4 {

    private static Singleton4 instance;

    // 構(gòu)造函數(shù)是私有的
    private Singleton4() {

    }

    // 這種寫法雖然是線程安全的,但是效率太低,不推薦用
    public synchronized static Singleton4 getInstance() {
        if (instance == null) {
            instance = new Singleton4();
        }
        return instance;
    }
}

同步代碼塊(線程不安全,不可用)

/**
 * 懶漢式(線程不安全)(不可用)
 */
public class Singleton5 {

    private static Singleton5 instance;

    // 構(gòu)造函數(shù)是私有的
    private Singleton5() {

    }

    public static Singleton5 getInstance() {
        // 這種寫法并不是線程安全的,不可用
        if (instance == null) {
            synchronized (Singleton5.class) {
                instance = new Singleton5();
            }
        }
        return instance;
    }
}

雙重檢查 + volatile(推薦用)

優(yōu)點(diǎn):線程安全,延遲加載,效率較高。

/**
 * 雙重檢查 + volatile(推薦用)
 */
public class Singleton6 {

    // volatile防止重排序
    private volatile static Singleton6 instance;

    // 構(gòu)造函數(shù)是私有的
    private Singleton6() {

    }

    public static Singleton6 getInstance() {
        // 雙重檢查保證線程安全
        if (instance == null) {
            synchronized (Singleton6.class) {
                if (instance == null) {
                    instance = new Singleton6();
                }
            }
        }
        return instance;
    }
}

為什么要用 volatile?

新建對(duì)象 rs = new Resource() 實(shí)際上有 3 個(gè)步驟:

  • construct empty resource()
  • call constructor
  • assign to rs

如下圖所示,重排序會(huì)帶來NPE問題(NullPointerException, 空指針異常),而使用 volatile 可以防止重排序。

單例模式的八種寫法、單例和并發(fā)的關(guān)系,Java,單例模式,java,設(shè)計(jì)模式

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

/**
 * 靜態(tài)內(nèi)部類(線程安全,懶加載)(推薦用)
 */
public class Singleton7 {

    // 構(gòu)造函數(shù)是私有的
    private Singleton7() {

    }

    // 由JVM的規(guī)定可知,這種寫法同時(shí)滿足了線程安全和懶加載兩個(gè)優(yōu)點(diǎn)
    private static class SingletonInstance {
        private static final Singleton7 INSTANCE = new Singleton7();
    }

    public static Singleton7 getInstance() {
        return SingletonInstance.INSTANCE;
    }
}

枚舉(推薦用)

單例模式的書寫:

/**
 * 枚舉(線程安全,懶加載)(推薦用)
 */
public enum Singleton8 {
    INSTANCE;

    public void whatever() {

    }
}

單例的使用:

Singleton8.INSTANCE.whatever();

哪種單例的實(shí)現(xiàn)方案最好?

Joshua Bloch 大神在《Effective Java》中明確表達(dá)過的觀點(diǎn):使用枚舉實(shí)現(xiàn)單例的方法雖然還沒有廣泛采用,但是單元素的枚舉類型已經(jīng)成為實(shí)現(xiàn) Singleton 的最佳方法。文章來源地址http://www.zghlxwxcb.cn/news/detail-799856.html

  • 寫法簡單
  • 線程安全有保障
  • 懶加載
  • 避免反序列化破壞單例

到了這里,關(guān)于單例模式的八種寫法、單例和并發(fā)的關(guān)系的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • STM32 GPIO的八種工作模式各有特點(diǎn),適用于不同的應(yīng)用場景

    學(xué)了挺久的單片機(jī)老是記不住每種模式的運(yùn)用場景今天用通義千問總結(jié)了一下作為鞭策順便記錄一下 STM32 GPIO的八種工作模式各有特點(diǎn),適用于不同的應(yīng)用場景。以下是每種模式的簡要描述及其對(duì)應(yīng)的應(yīng)用場景: 1. **GPIO_Mode_AIN** - **模擬輸入** ? ?- **應(yīng)用場景**: 當(dāng)GPIO引腳作為

    2024年04月11日
    瀏覽(94)
  • Java List集合取交集的八種不同實(shí)現(xiàn)方式

    Java List集合取交集的八種不同實(shí)現(xiàn)方式

    碼到三十五 : 個(gè)人主頁 心中有詩畫,指尖舞代碼,目光覽世界,步履越千山,人間盡值得 ! 在Java中,取兩個(gè)List集合的交集可以通過多種方式實(shí)現(xiàn),包括使用Java 8的Stream API、傳統(tǒng)的for循環(huán)遍歷、使用集合的retainAll方法,以及使用Apache Commons Collections庫等。 方法一:使用Jav

    2024年04月12日
    瀏覽(16)
  • 單例模式有幾種寫法?【如何實(shí)現(xiàn)單例模式?】

    專注 效率 記憶 預(yù)習(xí) 筆記 復(fù)習(xí) 做題 歡迎觀看我的博客,如有問題交流,歡迎評(píng)論區(qū)留言,一定盡快回復(fù)?。ù蠹铱梢匀タ次业膶冢撬形恼碌哪夸洠?文章字體風(fēng)格: 紅色文字表示:重難點(diǎn)★? 藍(lán)色文字表示:思路以及想法★? 如果大家覺得有幫助的話,感謝大家?guī)?/p>

    2024年02月07日
    瀏覽(21)
  • python安裝包(模塊)的八種方法

    easy_install 這應(yīng)該是最古老的包安裝方式了,目前基本沒有人使用了。下面是 easy_install 的一些安裝示例 pip 是最主流的包管理方案,使用 pip install xxx 就可以從 PYPI 上搜索并安裝 xxx (如果該包存在的話)。 下面僅列出一些常用的 pip install 的安裝示例 更多 pip 的使用方法,可

    2024年02月05日
    瀏覽(16)
  • Spring 事務(wù)失效的八種場景

    Spring 事務(wù)失效的八種場景

    原因:Spring 默認(rèn)只會(huì)回滾非檢查異常 解法:配置 rollbackFor 屬性 @Transactional(rollbackFor = Exception.class) 原因:事務(wù)通知只有捉到了目標(biāo)拋出的異常,才能進(jìn)行后續(xù)的回滾處理,如果目標(biāo)自己處理掉異常,事務(wù)通知無法知悉 解法1:異常原樣拋出: 在 catch 塊添加 throw new RuntimeExc

    2024年02月14日
    瀏覽(17)
  • 【Java|多線程與高并發(fā)】設(shè)計(jì)模式-單例模式(餓漢式,懶漢式和靜態(tài)內(nèi)部類)

    【Java|多線程與高并發(fā)】設(shè)計(jì)模式-單例模式(餓漢式,懶漢式和靜態(tài)內(nèi)部類)

    設(shè)計(jì)模式是一種在軟件開發(fā)中常用的解決復(fù)雜問題的方法論。它提供了一套經(jīng)過驗(yàn)證的解決方案,用于解決特定類型問題的設(shè)計(jì)和實(shí)現(xiàn)。設(shè)計(jì)模式可以幫助開發(fā)人員提高代碼的可重用性、可維護(hù)性和可擴(kuò)展性。 設(shè)計(jì)模式有很多,本文主要介紹單例模式. 單例模式是一種創(chuàng)建型設(shè)

    2024年02月11日
    瀏覽(28)
  • 【Flink】Flink 的八種分區(qū)策略(源碼解讀)

    【Flink】Flink 的八種分區(qū)策略(源碼解讀)

    Flink 包含 8 種分區(qū)策略,這 8 種分區(qū)策略(分區(qū)器)分別如下面所示,本文將從源碼的角度解讀每個(gè)分區(qū)器的實(shí)現(xiàn)方式。 GlobalPartitioner ShufflePartitioner RebalancePartitioner RescalePartitioner BroadcastPartitioner ForwardPartitioner KeyGroupStreamPartitioner CustomPartitionerWrapper 該分區(qū)器會(huì)將所有的數(shù)據(jù)都

    2024年04月10日
    瀏覽(30)
  • Selenium元素定位的八種方法(建議收藏)

    Selenium元素定位的八種方法(建議收藏)

    自動(dòng)化一般需要四步操作:獲取元素,操作元素,獲取返回結(jié)果,斷言(返回結(jié)果與期望結(jié)果是否一致),最后自動(dòng)出測試報(bào)告。Selenium提供8種元素定位的方法:id,name,class name,link text,xpath,css selector,tag name ,partial link tex。 這八種元素定位方法用python語言表示為: find_element_b

    2024年02月09日
    瀏覽(17)
  • HTTP/1.1協(xié)議中的八種請(qǐng)求

    2023年8月29日,周二晚上 目錄 概述八種請(qǐng)求 GET請(qǐng)求 POST請(qǐng)求 PUT請(qǐng)求 PATCH請(qǐng)求 DELETE請(qǐng)求 HEAD請(qǐng)求 OPTIONS請(qǐng)求 TRACE請(qǐng)求 ?HTTP/1.1協(xié)議中定義了8種常用的請(qǐng)求方法,分別是: 1. GET 用途:請(qǐng)求指定的頁面信息,并返回實(shí)體主體。 例子:獲取一個(gè)網(wǎng)頁、圖片等靜態(tài)內(nèi)容。 2. POST? 用途:向指定

    2024年02月09日
    瀏覽(22)
  • Mysql 提升索引效率優(yōu)化的八種方法

    目錄 1. 選擇唯一性索引 2. 為經(jīng)常需要排序、分組和聯(lián)合操作的字段建立索引 3. 為常作為查詢條件的字段建立索引 4. 限制索引的數(shù)目 5. 盡量使用數(shù)據(jù)量少的索引 6. 數(shù)據(jù)量小的表最好不要使用索引 7. 盡量使用前綴來索引 8. 刪除不再使用或者很少使用的索引 總結(jié) 索引的設(shè)計(jì)可

    2024年04月26日
    瀏覽(88)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包