欧美成人午夜免费全部完,亚洲午夜福利精品久久,а√最新版在线天堂,另类亚洲综合区图片小说区,亚洲欧美日韩精品色xxx

廣州Java培訓之單例設(shè)計模式的線程同步

2018-04-19 13:35:04 1225瀏覽

單例模式是最常用的設(shè)計模式之一,目的是保證一個類只有一個實例。



在項目中的作用:


1、解決因為頻繁創(chuàng)建對象,導致資源消耗過大的問題,如:數(shù)據(jù)庫的連接池,連接池用于創(chuàng)建數(shù)據(jù)庫連接,并對連接進行回收使用,能減少數(shù)據(jù)庫連接的創(chuàng)建次數(shù),從而提高效率,但是連接池對象本身在項目中只需要一個,就需要使用單例模式。類似的還有線程池等。

2、項目中能共享的工具類,如Java中的Runtime類能提供各種運行環(huán)境系統(tǒng)參數(shù),它就被設(shè)計成了單例模式。

實現(xiàn)單例的過程:

1、要保證類只能創(chuàng)建一個對象,就必須隱藏類的構(gòu)造方法,所以要將構(gòu)造方法定義為私有的

2、在類中調(diào)用構(gòu)造方法創(chuàng)建對象,定義靜態(tài)方法用于返回對象。

下面這種單例模式屬于餓漢式單例模式,既一開始就將對象實例化。這樣的做法會導致性能的降低,一般我們會采用延遲加載的方式,既需要對象時再實例化。

  classHunger{
  //靜態(tài)的實例
  privatestaticHungerhunger=newHunger();
  //隱藏構(gòu)造方法
  privateHunger(){}
  //返回靜態(tài)實例
  publicstaticHungergetInstance(){
  returnhunger;
  }
  }

下面這種是懶漢式單例模式,既開始不實例化對象,到需要該實例時再實例化,提高了運行效率。

  publicclassLazySingleton{
  //靜態(tài)的實例
  privatestaticLazySingletonsingle=null;
  //隱藏構(gòu)造方法
  privateLazySingleton(){
  System.out.println("創(chuàng)建LazySingleton對象");
  }
  //返回靜態(tài)實例
  publicstaticLazySingletongetInstance(){
  if(single==null){
  single=newLazySingleton();
  }
  returnsingle;
  }
  }

線程安全問題:懶漢單例模式在單線程環(huán)境沒有問題,但在多線程環(huán)境下就會出現(xiàn)問題。

執(zhí)行代碼,"創(chuàng)建LazySingleton對象"這句話會輸出多次,也就是創(chuàng)建了多個對象。

  for(inti=0;i<100;i++){
  newThread(newRunnable(){
  @Override
  publicvoidrun(){
  System.out.println(LazySingleton.getInstance());
  }}).start();
  }

分析原因:

假設(shè)線程1滿足getInstance方法中single==null條件后,準備執(zhí)行創(chuàng)建對象的代碼,然后CPU被其它線程搶占,其它線程在getInstance方法中創(chuàng)建對象,然后線程1搶回CPU繼續(xù)執(zhí)行剛才未完成的創(chuàng)建對象代碼,這樣就創(chuàng)建了多個對象。

線程同步問題的解決方法:

1、使用同步方法

publicstaticsynchronizedLazySingletongetInstance(){
if(single==null){
single=newLazySingleton();
}
returnsingle;
}
執(zhí)行剛才多線程的代碼后,我們發(fā)現(xiàn)可以解決同步問題,但是同步方法存在的問題是每個線程進入后都會加鎖,執(zhí)行效率低。

2、使用同步代碼塊配合if使用

publicstaticLazySingletongetInstance(){
if(single==null){
synchronized(LazySingleton.class){
single=newLazySingleton();
}
}
returnsingle;
}

同步塊和if語句配合使用,解決了每次都執(zhí)行上鎖導致的性能問題,但是運行代碼后我們會發(fā)現(xiàn),多線程同步的問題還是可能出現(xiàn),原因是多個線程還是可能會同時進入if語句。

3、使用雙重判斷

在同步塊中再添加一次if判斷就解決了上面的問題,因為就算多個線程同時進入外層if語句,執(zhí)行同步塊還是要進行一次判斷,這樣第一個線程創(chuàng)建對象后,后面的線程就不能再創(chuàng)建了。

  publicstaticLazySingletongetInstance(){
  //外層的if主要作用是判斷是否需要執(zhí)行同步塊,提高性能
  if(single==null){
  //靜態(tài)方法中將類作為鎖
  synchronized(LazySingleton.class){
  //判斷對象是否為空,為空就創(chuàng)建對象
  if(single==null){
  single=newLazySingleton();
  }
  }
  }
  returnsingle;
  }

4、靜態(tài)內(nèi)部類

這種方法結(jié)合了餓漢式和懶漢式的特點,如果不調(diào)用getInstance方法,靜態(tài)內(nèi)部類中的創(chuàng)建對象代碼不會執(zhí)行,調(diào)用getInstance后才會執(zhí)行,也就有了懶漢式延遲加載的效果,并且由于對象是直接創(chuàng)建的,還不存在線程同步問題。

  classMySingleton{
  privateMySingleton(){
  }
  privatestaticclassSingletonHelp{
  staticMySingletoninstance=newMySingleton();
  }
  publicstaticMySingletongetInstance(){
  returnSingletonHelp.instance;
  }
  }


總結(jié):單例模式的實現(xiàn)一般有餓漢式、懶漢式和靜態(tài)內(nèi)部類等方式,餓漢式創(chuàng)建對象的性能比較低但不存在線程同步問題,懶漢式由于是延遲加載性能更高,但存在線程同步問題,需要使用雙重判斷解決,靜態(tài)內(nèi)部類的方式也能實現(xiàn)單例模式但是代碼可讀性稍差。

如果項目對性能不敏感推薦使用餓漢式,如果是單線程環(huán)境可以使用一般的懶漢式,如果需要多線程則可以使用多重判斷的懶漢式或靜態(tài)內(nèi)部類實現(xiàn)。

以上就是關(guān)于Java開發(fā)單例設(shè)計模式線程同步的詳細介紹,最后想要了解更多可以登錄扣丁學堂官網(wǎng)咨詢??鄱W堂是專業(yè)的Java培訓機構(gòu),不僅有專業(yè)的老師和與時俱進的課程體系,還有大量的Java視頻教程供學員觀看學習,想要學好JavaEE的小伙伴抓緊時間行動吧。Java技術(shù)交流群:670348138。



關(guān)注微信公眾號獲取更多學習資料



關(guān)注微信公眾號獲取更多學習資料



查看更多關(guān)于“Java開發(fā)資訊的相關(guān)文章>>

標簽: Java視頻教程 Java培訓 Java開發(fā)工程師 廣州Java培訓 Java在線教程 Java在線視頻

熱門專區(qū)

暫無熱門資訊

課程推薦

微信
微博
15311698296

全國免費咨詢熱線

郵箱:codingke@1000phone.com

官方群:148715490

北京千鋒互聯(lián)科技有限公司版權(quán)所有   北京市海淀區(qū)寶盛北里西區(qū)28號中關(guān)村智誠科創(chuàng)大廈4層
京ICP備2021002079號-2   Copyright ? 2017 - 2022
返回頂部 返回頂部