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

單例模式 分析代碼優(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)文章

最新評論

苍南县| 鄂伦春自治旗| 栖霞市| 珠海市| 古丈县| 都匀市| 惠水县| 侯马市| 延川县| 武隆县| 浮梁县| 宽甸| 三台县| 新郑市| 富蕴县| 波密县| 桦川县| 古交市| 汉川市| 明水县| 荣成市| 灵丘县| 高尔夫| 安徽省| 周口市| 正宁县| 阿勒泰市| 佛学| 沛县| 天等县| 万山特区| 三河市| 长兴县| 诏安县| 文山县| 九龙坡区| 临汾市| 涞源县| 侯马市| 沙雅县| 桑植县|