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

JAVA實(shí)現(xiàn)單例模式的四種方法和一些特點(diǎn)

 更新時(shí)間:2013年03月26日 09:52:51   作者:  
JAVA實(shí)現(xiàn)單例模式的四種方法和一些特點(diǎn),需要的朋友可以參考一下

一、餓漢式單例類

復(fù)制代碼 代碼如下:

public class Singleton 

    private Singleton(){ 

    } 

    private static Singleton instance = new Singleton(); 

    private static Singleton getInstance(){ 
        return instance; 
    } 

特點(diǎn):餓漢式提前實(shí)例化,沒(méi)有懶漢式中多線程問(wèn)題,但不管我們是不是調(diào)用getInstance()都會(huì)存在一個(gè)實(shí)例在內(nèi)存中

二、內(nèi)部類式單例類

復(fù)制代碼 代碼如下:

public class Singleton    
{       
        private Singleton(){    

    }    

    private class SingletonHoledr(){    
        private static Singleton instance = new Singleton();    
    }    

    private static Singleton getInstance(){    
        return SingletonHoledr.instance;    
    }    
}

特點(diǎn):內(nèi)部類式中,實(shí)現(xiàn)了延遲加載,只有我們調(diào)用了getInstance(),才會(huì)創(chuàng)建唯一的實(shí)例到內(nèi)存中.并且也解決了懶漢式中多線程的問(wèn)題.解決的方式是利用了Classloader的特性.

三、懶漢式單例類

復(fù)制代碼 代碼如下:

public class Singleton    
{       
    private Singleton(){    

    }    

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

特點(diǎn):在懶漢式中,有線程A和B,當(dāng)線程A運(yùn)行到第8行時(shí),跳到線程B,當(dāng)B也運(yùn)行到8行時(shí),兩個(gè)線程的instance都為空,這樣就會(huì)生成兩個(gè)實(shí)例。解決的辦法是同步:

可以同步但是效率不高:

復(fù)制代碼 代碼如下:

public class Singleton    
{       
    private Singleton(){    

    }    

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

這樣寫程序不會(huì)出錯(cuò),因?yàn)檎麄€(gè)getInstance是一個(gè)整體的"critical section",但就是效率很不好,因?yàn)槲覀兊哪康钠鋵?shí)只是在第一個(gè)初始化instance的時(shí)候需要locking(加鎖),而后面取用instance的時(shí)候,根本不需要線程同步。

于是聰明的人們想出了下面的做法:

雙檢鎖寫法:

復(fù)制代碼 代碼如下:

public class Singleton{ 
  private static Singleton single;    //聲明靜態(tài)的單例對(duì)象的變量 
  private Singleton(){}    //私有構(gòu)造方法  

  public static Singleton getSingle(){    //外部通過(guò)此方法可以獲取對(duì)象   
    if(single == null){    
        synchronized (Singleton.class) {   //保證了同一時(shí)間只能只能有一個(gè)對(duì)象訪問(wèn)此同步塊       
            if(single == null){     
                single = new Singleton();         
        }    
      } 
    }   
    return single;   //返回創(chuàng)建好的對(duì)象  
  } 

思路很簡(jiǎn)單,就是我們只需要同步(synchronize)初始化instance的那部分代碼從而使代碼既正確又很有效率。
這就是所謂的“雙檢鎖”機(jī)制(顧名思義)。
很可惜,這樣的寫法在很多平臺(tái)和優(yōu)化編譯器上是錯(cuò)誤的。

原因在于:instance = new Singleton()這行代碼在不同編譯器上的行為是無(wú)法預(yù)知的。一個(gè)優(yōu)化編譯器可以合法地如下實(shí)現(xiàn)instance = new Singleton():

1. instance  = 給新的實(shí)體分配內(nèi)存

2. 調(diào)用Singleton的構(gòu)造函數(shù)來(lái)初始化instance的成員變量

現(xiàn)在想象一下有線程A和B在調(diào)用getInstance,線程A先進(jìn)入,在執(zhí)行到步驟1的時(shí)候被踢出了cpu。然后線程B進(jìn)入,B看到的是instance  已經(jīng)不是null了(內(nèi)存已經(jīng)分配),于是它開(kāi)始放心地使用instance,但這個(gè)是錯(cuò)誤的,因?yàn)樵谶@一時(shí)刻,instance的成員變量還都是缺省值,A還沒(méi)有來(lái)得及執(zhí)行步驟2來(lái)完成instance的初始化。

當(dāng)然編譯器也可以這樣實(shí)現(xiàn):

1. temp = 分配內(nèi)存

2. 調(diào)用temp的構(gòu)造函數(shù)

3. instance = temp

如果編譯器的行為是這樣的話我們似乎就沒(méi)有問(wèn)題了,但事實(shí)卻不是那么簡(jiǎn)單,因?yàn)槲覀儫o(wú)法知道某個(gè)編譯器具體是怎么做的,因?yàn)樵贘ava的memory model里對(duì)這個(gè)問(wèn)題沒(méi)有定義。

雙檢鎖對(duì)于基礎(chǔ)類型(比如int)適用。很顯然吧,因?yàn)榛A(chǔ)類型沒(méi)有調(diào)用構(gòu)造函數(shù)這一步。

相關(guān)文章

  • 解決SpringBoot log4j日志沒(méi)生成的問(wèn)題

    解決SpringBoot log4j日志沒(méi)生成的問(wèn)題

    這篇文章主要介紹了解決SpringBoot log4j日志沒(méi)生成的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java正則驗(yàn)證字串符RegexValidator類使用

    Java正則驗(yàn)證字串符RegexValidator類使用

    正則驗(yàn)證字串符是一種強(qiáng)大的工具,可以幫助程序員在處理字符串時(shí)輕松進(jìn)行復(fù)雜匹配,本文將介紹正則表達(dá)式的概念、語(yǔ)法和在編程中的應(yīng)用,并通過(guò)實(shí)例演示如何使用正則表達(dá)式進(jìn)行字符串匹配、替換和提取等操作
    2023-11-11
  • Java實(shí)現(xiàn)解析.xlsb文件的示例代碼

    Java實(shí)現(xiàn)解析.xlsb文件的示例代碼

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)解析.xlsb文件的相關(guān)方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的可以了解一下
    2023-01-01
  • SpringBoot調(diào)用第三方WebService接口的兩種方法

    SpringBoot調(diào)用第三方WebService接口的兩種方法

    本文主要介紹了SpringBoot調(diào)用第三方WebService接口的兩種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • SpringCloud手寫Ribbon實(shí)現(xiàn)負(fù)載均衡

    SpringCloud手寫Ribbon實(shí)現(xiàn)負(fù)載均衡

    這篇文章主要介紹了SpringCloud手寫Ribbon實(shí)現(xiàn)負(fù)載均衡的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • IDEA卡在”正在解析Maven依賴項(xiàng)“的解決方法

    IDEA卡在”正在解析Maven依賴項(xiàng)“的解決方法

    在創(chuàng)建新的SpringBoot項(xiàng)目時(shí),始終卡在"正在解析Maven依賴項(xiàng)…",本文小編給大家介紹了幾種相關(guān)的解決方案,具有一定的參考價(jià)值,需要的朋友可以參考下
    2023-11-11
  • MyBatis使用注解開(kāi)發(fā)實(shí)現(xiàn)過(guò)程詳解

    MyBatis使用注解開(kāi)發(fā)實(shí)現(xiàn)過(guò)程詳解

    這篇文章主要介紹了MyBatis使用注解開(kāi)發(fā)實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • SpringCloud?Feign集成AOP的常見(jiàn)問(wèn)題與解決

    SpringCloud?Feign集成AOP的常見(jiàn)問(wèn)題與解決

    在使用?Spring?Cloud?Feign?作為微服務(wù)通信的工具時(shí),我們可能會(huì)遇到?AOP?不生效的問(wèn)題,這篇文章將深入探討這一問(wèn)題,給出幾種常見(jiàn)的場(chǎng)景,分析可能的原因,并提供解決方案,希望對(duì)大家有所幫助
    2023-10-10
  • Java實(shí)現(xiàn)多任務(wù)執(zhí)行助手

    Java實(shí)現(xiàn)多任務(wù)執(zhí)行助手

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)多任務(wù)執(zhí)行助手,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 解決spring 處理request.getInputStream()輸入流只能讀取一次問(wèn)題

    解決spring 處理request.getInputStream()輸入流只能讀取一次問(wèn)題

    這篇文章主要介紹了解決spring 處理request.getInputStream()輸入流只能讀取一次問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09

最新評(píng)論