亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java的單例設(shè)計(jì)模式詳解

 更新時(shí)間:2018年12月22日 15:52:42   作者:pigdreams  
今天小編就為大家分享一篇關(guān)于Java的單例設(shè)計(jì)模式詳解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧

1.什么是單例模式

  • 生成一個(gè)獨(dú)一無二的,保證任何時(shí)刻一個(gè)類只有一個(gè)實(shí)例的模式
  • 確保一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn)
  • 可以在需要時(shí)才創(chuàng)建對(duì)象,避免了全局變量在程序啟動(dòng)時(shí)就得創(chuàng)建對(duì)象的缺點(diǎn)。

2.經(jīng)典單例模式實(shí)現(xiàn)

public class MyInstance{
 //第一步:私有化構(gòu)造器,只有類自身才能調(diào)用構(gòu)造器外部類不能夠直接new出這個(gè)類的實(shí)例對(duì)象
 private MyInstance(){}
 //第二步:聲明一個(gè)全局靜態(tài)變量來記錄自身實(shí)例的對(duì)象,也是私有的,限制其它外部類訪問
 private static MyInstance myInstance;
 //第三步:提供一個(gè)外部可訪問的靜態(tài)公開方法,來獲得該類的唯一實(shí)例
 public static MyInstance getMyInstance(){
 //第四步:進(jìn)行判斷自身類對(duì)象如果為空,則創(chuàng)建一個(gè)實(shí)例
 if(myInstance==null){
  //這里的方法只執(zhí)行了一次,生成了一個(gè)唯一的類對(duì)象
  myInstance=new MyInstance();
 }
 //第五步:如果不為空,則返回該類對(duì)象,故由始至終,該類對(duì)象只初始化過一次,只有一個(gè)對(duì)象存在,這就是單例模式
 return myInstance;
 }
}

3.經(jīng)典模式存在的缺陷

這種經(jīng)典模式也稱之為懶漢式單例模式(lazy instantiaze),因?yàn)樗茄舆t化實(shí)例化的,即如果我們不需要這個(gè)實(shí)例,則它永遠(yuǎn)不會(huì)被初始化,只有在調(diào)用過一次實(shí)例化方法后,才會(huì)被創(chuàng)建出對(duì)象。

在多線程的情況下可能會(huì)產(chǎn)生并發(fā)問題,因?yàn)楂@取單例的方法getMyInstance()有可能被多個(gè)線程同時(shí)訪問,這時(shí)就會(huì)有可能 創(chuàng)建出兩個(gè)以上的實(shí)例對(duì)象。這就要考慮要線程安全的問題了,解決問題就是在獲取實(shí)例方法處加一個(gè)同步鎖,這樣就能輕松地解決線程并發(fā)的問題了。

public static synchronized MyInstance getMyInstance(){
 //加同步鎖關(guān)鍵字synchronized,這樣在有線程訪問這個(gè)方法時(shí),其它線程只能等待當(dāng)前線程訪問結(jié)束才能訪問這個(gè)方法。
 if(myInstance==null){
  //這里的方法只執(zhí)行了一次,生成了一個(gè)唯一的類對(duì)象
  myInstance=new MyInstance();
 }

4.多線程下同步所造成的性能問題

如果將獲取實(shí)例的方法進(jìn)行同步的話,會(huì)造成程序執(zhí)行的效率大大地下降,而且單例對(duì)象生成只要調(diào)用一次方法即可,之后每次調(diào)用這個(gè)方法時(shí),同步都是一種累綴,有可能會(huì)拖垮程序的性能。

當(dāng)然如果你的程序?qū)τ谛阅艿囊蟛⒉皇呛芨叩脑挘猛降姆椒ǐ@取單例是最簡(jiǎn)單而有效的。

為保證程序的性能并且又不會(huì)出現(xiàn)并發(fā)的問題,可以使用另一種生成單例對(duì)象的模式,叫做餓漢式單例模式(eagerly instantiaze)

public class MyInstance{
 //第一步:私有化構(gòu)造器
 private MyInstance(){}
 //第二步:聲明一個(gè)全局靜態(tài)變量來記錄自身實(shí)例的對(duì)象,并進(jìn)行實(shí)例化
 private static MyInstance myInstance=new MyInstance();
 //第三步:提供一個(gè)外部可訪問的靜態(tài)公開方法,來獲得該類的唯一實(shí)例
 public static MyInstance getMyInstance(){
 return myInstance;
 }

這個(gè)模式使JVM在加載這個(gè)類時(shí)會(huì)馬上創(chuàng)建唯一的單例對(duì)象,這樣就能保證任何線程訪問靜態(tài)單例變量myInstance時(shí),單例對(duì)象一定被實(shí)例化過了。

5.利用雙重檢查加鎖來提升性能

  • 首先檢查實(shí)例是否已經(jīng)創(chuàng)建了,如果沒有才進(jìn)行同步獲取實(shí)例的方法,這樣就保證了實(shí)例方法只會(huì)在第一次獲取實(shí)例時(shí)會(huì)同步。
  • 這里要用到一個(gè)關(guān)鍵字volatile,此關(guān)鍵字確保了當(dāng)實(shí)例變量myInstance被初始化成實(shí)例對(duì)象時(shí),多個(gè)線程能正確地處理實(shí)例變量。注意,這個(gè)關(guān)鍵字只有在Java1.5及以上的版本才會(huì)對(duì)雙重檢查加載生效。
public class MyInstance{
 //用關(guān)鍵字volatile修飾實(shí)例變量
 private volatile static MyInstance myInstance;
 //私有化構(gòu)造器
 private MyInstance(){}
 public static MyInstance getMyInstance(){
 //第一次檢查實(shí)例是否存在
 if(myInstance==null){
  //如果不存在則進(jìn)入同步區(qū)塊
  synchronized (MyInstance.class){
  if(myInstance==null){
   //第二次檢查,如果不為空才真正創(chuàng)建實(shí)例對(duì)象
   myInstance=new MyInstance();
  }
  } 
 }
 //如果不為空,則直接返回該類對(duì)象
 return myInstance;
 }
}

單例模式的所有情況都已經(jīng)總結(jié)完畢,一開始以為單例模式應(yīng)該是所有設(shè)計(jì)模式中最簡(jiǎn)單易懂的了,沒想到看到四人幫的HeadFirst設(shè)計(jì)模式后發(fā)現(xiàn)還有這么多門道,真的是學(xué)無止境。

注:以上所有內(nèi)容皆總結(jié)自《HeadFirst 設(shè)計(jì)模式》

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接

相關(guān)文章

  • SpringBoot使用@Value實(shí)現(xiàn)給靜態(tài)變量注入值

    SpringBoot使用@Value實(shí)現(xiàn)給靜態(tài)變量注入值

    這篇文章主要介紹了SpringBoot使用@Value實(shí)現(xiàn)給靜態(tài)變量注入值的方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • hystrix配置中Apollo與Archaius對(duì)比分析

    hystrix配置中Apollo與Archaius對(duì)比分析

    這篇文章主要為大家介紹了hystrix的配置中Apollo與Archaius對(duì)比分析,并為大家解答在hystrix的配置中有了Apollo是否還需要Archaius這一問題詳解
    2022-02-02
  • java使用正則表達(dá)式判斷郵箱格式是否正確的方法

    java使用正則表達(dá)式判斷郵箱格式是否正確的方法

    這篇文章主要介紹了java使用正則表達(dá)式判斷郵箱格式是否正確的方法,涉及java正則表達(dá)式及字符串的相關(guān)操作技巧,需要的朋友可以參考下
    2015-07-07
  • 淺談Storm在zookeeper上的目錄結(jié)構(gòu)

    淺談Storm在zookeeper上的目錄結(jié)構(gòu)

    這篇文章主要介紹了淺談Storm在zookeeper上的目錄結(jié)構(gòu)的相關(guān)內(nèi)容,涉及storm使用zookeeper的操作以及詳細(xì)結(jié)構(gòu)圖,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-10-10
  • Java中synchronized實(shí)現(xiàn)原理詳解

    Java中synchronized實(shí)現(xiàn)原理詳解

    這篇文章主要介紹了Java中synchronized實(shí)現(xiàn)原理詳解,涉及synchronized實(shí)現(xiàn)同步的基礎(chǔ),Java對(duì)象頭,Monitor,Mark Word,鎖優(yōu)化,自旋鎖等相關(guān)內(nèi)容,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-11-11
  • java爬蟲Jsoup主要類及功能使用詳解

    java爬蟲Jsoup主要類及功能使用詳解

    這篇文章主要為大家介紹了java爬蟲Jsoup主要類及功能使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Java多線Condition條件變量正確使用方法詳解

    Java多線Condition條件變量正確使用方法詳解

    這篇文章主要為大家,介紹了Java多線Condition條件變量正確使用方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • 5分鐘讓你快速掌握java8 stream常用開發(fā)技巧

    5分鐘讓你快速掌握java8 stream常用開發(fā)技巧

    這篇文章主要給大家介紹了關(guān)于java8 stream常用開發(fā)技巧的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Java調(diào)用opencv實(shí)現(xiàn)圖片矯正功能

    Java調(diào)用opencv實(shí)現(xiàn)圖片矯正功能

    這篇文章主要為大家詳細(xì)介紹了Java如何調(diào)用opencv實(shí)現(xiàn)圖片矯正功能,文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-09-09
  • springboot中mybatis多數(shù)據(jù)源動(dòng)態(tài)切換實(shí)現(xiàn)

    springboot中mybatis多數(shù)據(jù)源動(dòng)態(tài)切換實(shí)現(xiàn)

    在開發(fā)中,動(dòng)態(tài)數(shù)據(jù)源配置還是用的比較多的,比如在多數(shù)據(jù)源使用方面,又或者是在多個(gè)DB之間切換方面。這里給出一個(gè)動(dòng)態(tài)數(shù)據(jù)源的配置方案,感興趣的可以了解一下
    2021-07-07

最新評(píng)論