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

單例模式 分析代碼優(yōu)化方法

 更新時(shí)間:2015年04月08日 22:44:30   作者:Cream.icend  
這篇文章主要介紹了單例模式 分析代碼優(yōu)化方法,需要的朋友可以參考下

單例模式是23種設(shè)計(jì)模式之一,是比較簡單的一種設(shè)計(jì)模式,它的目的是無論調(diào)用多少次,都返回同一個(gè)對象,它的特點(diǎn)是構(gòu)造器私有化。

  它分為兩種結(jié)構(gòu),一種是懶漢式的,一種是餓漢式的,它們各有優(yōu)缺點(diǎn),我們先從餓漢式看起,代碼如下:

public class Single { 
  private static Single single = new Single();  
  private Single() {  
  } 
   public Single getInstance() { 
    return single; 
  }  
}

通過上面的程序可以看出來雖然我們加載同一個(gè)對象的目的確實(shí)達(dá)到了,但當(dāng)程序被加載的時(shí)候就會創(chuàng)建single這個(gè)對象,當(dāng)這個(gè)類有多個(gè)這樣的方法時(shí),我們可能會用不到這個(gè)對象中大多數(shù)單例,就會造成對內(nèi)存的浪費(fèi)。所以就出現(xiàn)了懶漢式的單例模式,代碼如下:

public class Single { 
  private static Single single = null;  
  private Single() {  
  } 
 
  public Single getInstance() { 
    if(single==null){ 
      single = new Single(); 
    } 
    return single; 
  }  
}

這樣,只有當(dāng)我們真正調(diào)用這個(gè)對象時(shí)它才會被new出來,但是這樣是存在問題的。

  當(dāng)上面的第二段代碼在第一次加載的時(shí)候有兩個(gè)線程對其進(jìn)行了調(diào)用,則會產(chǎn)生兩個(gè)不同的對象,所以是線程不安全的,這時(shí)候就會想到給這個(gè)方法加個(gè)鎖,加鎖之后的代碼如下:

public class Single { 
  private static Single single = null;  
  private Single() {  
  } 
 
  public synchronized Single getInstance() { 
    if (single == null) { 
      single = new Single(); 
    } 
    return single; 
  }  
}

這樣做確實(shí)做到了線程安全,但是當(dāng)加鎖這個(gè)方法里面要執(zhí)行很多東西,調(diào)用這個(gè)方法花費(fèi)的時(shí)間會很長,這樣對服務(wù)器來說是致命的,因?yàn)檫@個(gè)方法如果某個(gè)線程一直調(diào)用的話,其它的線程是沒有辦法調(diào)的,服務(wù)器就阻塞了,那么升級后的代碼如下:

public class Single { 
  priate static Single single = null;  
  private Single() {  
  } 
 
  public Single getInstance() { 
    if (single == null) { 
      synchronized (Single.class) { 
        single = new Single(); 
      } 
    } 
    return single; 
  } 
}

仔細(xì)觀察以后發(fā)現(xiàn)這樣并沒有鎖住,當(dāng)?shù)谝淮瓮瑫r(shí)有兩個(gè)線程到達(dá)getInstance()方法if判斷時(shí),其中有一個(gè)肯定是阻塞的,當(dāng)另外一個(gè)執(zhí)行完以后,阻塞這個(gè)線程是不會再判斷是否為空的,還是會創(chuàng)建一個(gè)對象的,這樣又有多個(gè)對象被產(chǎn)生了,再對其進(jìn)行升級,得到的代碼如下:

public class Single { 
  private static Single single = null;  
  private Single() {  
  } 
 
  public Single getInstance() { 
    if (single == null) { 
      synchronized (Single.class) { 
        if (single == null) { 
          single = new Single(); 
        } 
      } 
    } 
    return single; 
  } 
}

這樣就不會產(chǎn)生上面的問題,而且也只鎖一次,因?yàn)榈诙卧賵?zhí)行這個(gè)方法時(shí),會跳過if判斷,直接返回single,不會再被鎖,執(zhí)行效率也會很高。

  但即使是這樣,也還是有問題的,因?yàn)槲覀儾荒艽_定在內(nèi)存中是先給對象賦值,還是先創(chuàng)建了這個(gè)對象,所以第二個(gè)程序有可能得到的是初始化一半了的對象,在jdk1.5之后,我們可以用volatile這個(gè)關(guān)鍵字來避免這種情況,代碼如下:

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

但是這種情況很少使用,我在這里只是為了學(xué)習(xí)一下,嘻嘻

相關(guān)文章

  • Java類初始化執(zhí)行流程解析

    Java類初始化執(zhí)行流程解析

    這篇文章主要介紹了Java類初始化執(zhí)行流程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-05-05
  • java實(shí)現(xiàn)二維碼掃碼授權(quán)登陸

    java實(shí)現(xiàn)二維碼掃碼授權(quán)登陸

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)二維碼掃碼授權(quán)登陸,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • SVN導(dǎo)入maven項(xiàng)目報(bào)錯解決方案

    SVN導(dǎo)入maven項(xiàng)目報(bào)錯解決方案

    這篇文章主要介紹了SVN導(dǎo)入maven項(xiàng)目報(bào)錯解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-12-12
  • SpringBoot整合Minio實(shí)現(xiàn)上傳文件的完整步驟記錄

    SpringBoot整合Minio實(shí)現(xiàn)上傳文件的完整步驟記錄

    MinIO是一個(gè)基于Apache License v2.0開源協(xié)議的對象存儲服務(wù),它兼容亞馬遜S3云存儲服務(wù)接口,非常適合于存儲大容量非結(jié)構(gòu)化的數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于SpringBoot整合Minio實(shí)現(xiàn)上傳文件的完整步驟,需要的朋友可以參考下
    2022-05-05
  • 詳解Spring如何解析占位符

    詳解Spring如何解析占位符

    Spring一直支持將屬性定義到外部的屬性的文件中,并使用占占位符的形式為使用"${}"包裝的屬性名稱,為了使用屬性占位符,我們必須配置一個(gè)PropertyPlaceholderConfigurer或PropertySourcesPlaceholderConfigurer實(shí)例,本文將介紹如何解析占位符
    2021-06-06
  • Spring中注解方式的異步請求

    Spring中注解方式的異步請求

    今天給大家整理了Spring中注解方式的異步請求的知識點(diǎn),對正在學(xué)習(xí)java的小伙伴們很有幫助,需要的朋友可以參考下
    2021-06-06
  • JDBC PreparedStatement Like參數(shù)報(bào)錯解決方案

    JDBC PreparedStatement Like參數(shù)報(bào)錯解決方案

    這篇文章主要介紹了JDBC PreparedStatement Like參數(shù)報(bào)錯解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Java入門案列之猜拳小游戲

    Java入門案列之猜拳小游戲

    這篇文章主要為大家詳細(xì)介紹了Java入門案列之猜拳小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • 淺談SpringBoot之開啟數(shù)據(jù)庫遷移的FlyWay使用

    淺談SpringBoot之開啟數(shù)據(jù)庫遷移的FlyWay使用

    這篇文章主要介紹了淺談SpringBoot之開啟數(shù)據(jù)庫遷移的FlyWay使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-01-01
  • AsyncConfigurerSupport自定義異步線程池處理異常

    AsyncConfigurerSupport自定義異步線程池處理異常

    這篇文章主要為大家介紹了AsyncConfigurerSupport自定義異步線程池處理異常詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06

最新評論