成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

小小的單例模式竟然有這么多種寫法?

開發(fā) 前端
單例模式應(yīng)該是設(shè)計模式中最容易理解也是用得最多的一種模式了,同時也是面試的時候最常被問到的模式。

[[404953]]

單例模式應(yīng)該是設(shè)計模式中最容易理解也是用得最多的一種模式了,同時也是面試的時候最常被問到的模式。

1. 單例模式的定義

單例模式指的是一個類中在任何情況下都絕對只有一個實例,并且提供一個全局訪問點。

2. 單例模式的應(yīng)用場景

單例模式的應(yīng)用非常廣泛,如數(shù)據(jù)庫中的連接池、J2EE中的ServletContext和ServletContextConfig、Spring框架中的ApplicationContext等等。然而在Java中,單例模式還可以保證一個JVM中只存在一個唯一的實例。

單例模式的應(yīng)用場景主要有以下幾個方面:

  • 當(dāng)需要頻繁創(chuàng)建一些類的時候,使用單例可以降低系統(tǒng)的內(nèi)存壓力,減少GC(垃圾回收) ;
  • 當(dāng)某些類創(chuàng)建實例時候需要占用的資源較多,或者實例化過程耗時比較長,且經(jīng)常使用的情況;
  • 當(dāng)存在頻繁訪問數(shù)據(jù)庫或者文件的對象;
  • 當(dāng)對于一些控制硬件級別的操作,或者從系統(tǒng)上來講應(yīng)當(dāng)是單一控制邏輯的操作,是不允許存在多個實例的,否則玩完;

3. 單例模式的優(yōu)缺點

3.1 單例模式的優(yōu)點

  • 單例模式可以保證內(nèi)存中只有一個實例對象,從而會減少內(nèi)存的開銷;
  • 單例模式可以避免對資源的多重占用;
  • 單例模式設(shè)置全局訪問點,可以起到優(yōu)化和共享資源的訪問的作用;

3.2 單例模式的缺點

  • 擴展難, 因為單例模式通常是沒有接口的啊,如果想要擴展,那么你唯一途徑就是修改之前的代碼,所以說單例模式違背了開閉原則;
  • 調(diào)試難,因為在并發(fā)測試中,單例模式是不利于代碼的調(diào)試的,單例中的代碼沒有執(zhí)行完,也不能模擬生成一個新對象;
  • 違背單一職責(zé)原則,因為單例模式的業(yè)務(wù)代碼通常寫在一個類中,如果功能設(shè)計不合理,就很容易違背單一職責(zé)原則;

4. 單例模式的實現(xiàn)方式及其優(yōu)缺點

4.1 單例模式的餓漢式實現(xiàn)

4.1.1 餓漢式標(biāo)準(zhǔn)寫法

Singleton類稱為單例類,通過內(nèi)部初始化一次 , 隱藏構(gòu)造方法, 并提供一個全局訪問點的方式實現(xiàn)。

  1. /** 
  2.  * msJava 
  3.  * 
  4.  * @Description 單例模式的通用寫法 
  5.  * @Date 2021-01-23 
  6.  */ 
  7. public class Singleton { 
  8.     /** 
  9.      * 內(nèi)部初始化一次 
  10.      */ 
  11.     private static final Singleton instance = new Singleton(); 
  12.  
  13.     /** 
  14.      * 隱藏構(gòu)造方法 
  15.      */ 
  16.     private Singleton() { 
  17.     } 
  18.  
  19.     /** 
  20.      * 提供一個全局訪問點 
  21.      * 
  22.      * @return Singleton 
  23.      */ 
  24.     public static Singleton getInstance() { 
  25.         return instance; 
  26.     } 
  27.  

以上餓漢式單例寫法在類的初始化的時候就會進行初始化操作,并且創(chuàng)建對象,絕對的線程安全,因為此時線程還沒有出現(xiàn)就已經(jīng)實例化了,故不會存在訪問安全的問題。

4.1.2 餓漢式靜態(tài)塊機制寫法

餓漢式還有一種實現(xiàn),那就是靜態(tài)塊機制,如下代碼所示:

  1. /** 
  2.  * msJava 
  3.  * 
  4.  * @Description 單例模式  餓漢式靜態(tài)機制 實現(xiàn) 
  5.  * @Date 2021-01-23 
  6.  */ 
  7. public class HungryStaticSingleton { 
  8.      
  9.     private static final HungryStaticSingleton hungrySingleton; 
  10.     //靜態(tài)代碼塊 類加載的時候就初始化 
  11.     static { 
  12.         hungrySingleton=new HungryStaticSingleton(); 
  13.     } 
  14.     /** 
  15.      * 私有化構(gòu)造函數(shù) 
  16.      */ 
  17.     private HungryStaticSingleton(){} 
  18.  
  19.     /** 
  20.      * 提供一個全局訪問點 
  21.      * @return 
  22.      */ 
  23.     public static HungryStaticSingleton getInstance() { 
  24.         return hungrySingleton; 
  25.     } 

我們分析一下這種是寫法 ,可以明顯的看到所以對象是類在加載的時候就進行實例化了,那么這樣一來,會導(dǎo)致單例對象的數(shù)量不確定,從而會導(dǎo)致系統(tǒng)初始化的時候就造成大量內(nèi)存浪費,況且你用不用還不一定,還一直占著空間,俗稱“占著茅坑不拉屎”。

4.2 單例模式的懶漢式實現(xiàn)

為了解決餓漢式單例寫法可能帶來的內(nèi)存浪費問題,這里分析一下懶漢式單例的寫法。如下代碼所示:

  1. /** 
  2.  * msJava 
  3.  * 
  4.  * @Description 單例模式  懶漢式單例實現(xiàn) 
  5.  * @Date 2021-01-23 
  6.  */ 
  7. public class LazySimpleSingleton { 
  8.  
  9.     private static LazySimpleSingleton lazySingleton = null
  10.  
  11.     /** 
  12.      * 私有化構(gòu)造函數(shù) 
  13.      */ 
  14.     private LazySimpleSingleton() { 
  15.  
  16.     } 
  17.     /** 
  18.      * 提供一個全局訪問點 
  19.      * 
  20.      * @return 
  21.      */ 
  22.     public static LazySimpleSingleton getInstance() { 
  23.         if (lazySingleton == null) { 
  24.             lazySingleton = new LazySimpleSingleton(); 
  25.         } 
  26.         return lazySingleton; 
  27.     } 

這樣實現(xiàn)的好處就是只有對象被使用的時候才會進行初始化,不會存在內(nèi)存浪費的問題,但是它會在多線程環(huán)境下,存在線程安全問題。我們可以利用synchronized關(guān)鍵字將全局訪問點方法變成一個同步方法,這樣就可以解決線程安全的問題,代碼如下所示:

  1. /** 
  2.  * msJava 
  3.  * 
  4.  * @Description 單例模式  懶漢式單例實現(xiàn) synchronized修飾  
  5.  * @Date 2021-01-23 
  6.  */ 
  7. public class LazySimpleSingleton { 
  8.     private static LazySimpleSingleton lazySingleton = null
  9.     /** 
  10.      * 私有化構(gòu)造函數(shù) 
  11.      */ 
  12.     private LazySimpleSingleton() {} 
  13.     /** 
  14.      * 提供一個全局訪問點   
  15.      * 
  16.      * @return 
  17.      */ 
  18.     public synchronized static  LazySimpleSingleton getInstance() { 
  19.         if (lazySingleton == null) { 
  20.             lazySingleton = new LazySimpleSingleton(); 
  21.         } 
  22.         return lazySingleton; 
  23.     } 

但是,這樣雖然解決了線程安全的問題,可是如果在線程數(shù)量劇增的情況下,用synchronized加鎖,則會導(dǎo)致大批線程阻塞,從而驟減系統(tǒng)性能。

4.3 單例模式的雙重檢測實現(xiàn)

在上述代碼上進一步優(yōu)化,代碼如下所示:

  1. /** 
  2.  * msJava 
  3.  * 
  4.  * @Description 單例模式  懶漢式-雙重檢測單例實現(xiàn) 
  5.  * @Date 2021-01-23 
  6.  */ 
  7. public class LazyDoubleCheckSingleton { 
  8.     // volatile 關(guān)鍵字修飾 
  9.     private volatile static LazyDoubleCheckSingleton lazySingleton ; 
  10.     /** 
  11.      * 私有化構(gòu)造函數(shù) 
  12.      */ 
  13.     private LazyDoubleCheckSingleton() {} 
  14.     /** 
  15.      * 提供一個全局訪問點 
  16.      * 
  17.      * @return 
  18.      */ 
  19.     public static LazyDoubleCheckSingleton getInstance() { 
  20.         // 這里先判斷一下是否阻塞 
  21.         if (lazySingleton == null) { 
  22.             synchronized (LazyDoubleCheckSingleton.class){ 
  23.                 // 判斷是否需要重新創(chuàng)建實例 
  24.                 if (lazySingleton == null) { 
  25.                     lazySingleton = new LazyDoubleCheckSingleton(); 
  26.                 } 
  27.             } 
  28.         } 
  29.         return lazySingleton; 
  30.     } 

()方法時,第二個線程也可以調(diào)用,但是第一個線程執(zhí)行synchronized時候,第二個線程就會發(fā)現(xiàn)阻塞,但是此時的阻塞是getInstance()內(nèi)部的阻塞。

4.4 單例模式的靜態(tài)內(nèi)部類實現(xiàn)

雖然雙重檢測鎖的單例模式解決了線程安全和性能問題,但是畢竟涉及加鎖的操作,多多少少就會到了性能的影響,下面我們分享一下更加優(yōu)雅的單例模式實現(xiàn),如下代碼所示:

  1. /** 
  2.  * msJava 
  3.  * 
  4.  * @Description 單例模式  靜態(tài)內(nèi)部類單例實現(xiàn) 
  5.  * @Date 2021-01-23 
  6.  */ 
  7. public class LazyStaticInnerClassSingleton { 
  8.     //  在構(gòu)造方法里面拋出異常真的合適? 
  9.   private LazyStaticInnerClassSingleton(){ 
  10.     if(LazyHolder.INSTANCE != null){ 
  11.         throw new RuntimeException("不允許創(chuàng)建多個實例"); 
  12.     } 
  13.   } 
  14.   // static 保證這個方法不會被重寫 覆蓋 
  15.   private static LazyStaticInnerClassSingleton getInstance(){ 
  16.       return LazyHolder.INSTANCE; 
  17.   } 
  18.   // Java 默認不會加載內(nèi)部類 
  19.   private static class LazyHolder{ 
  20.       private static final LazyStaticInnerClassSingleton INSTANCE=new LazyStaticInnerClassSingleton(); 
  21.   } 

5. 總結(jié)

 

單例模式面試幾乎必備!

 

責(zé)任編輯:武曉燕 來源: 碼上Java
相關(guān)推薦

2021-02-03 20:19:08

Istio流量網(wǎng)格

2020-11-02 08:35:59

內(nèi)存數(shù)據(jù)庫Redis

2016-09-01 13:54:23

Google太空電梯懸滑板

2013-01-24 09:44:44

數(shù)據(jù)庫

2020-06-01 08:04:18

三目運算符代碼

2024-05-13 16:22:25

固態(tài)硬盤接口硬盤

2022-03-03 07:00:43

Mybatiswhere標(biāo)簽

2015-05-18 15:08:08

多種程序設(shè)計語言程序設(shè)計語言

2024-04-02 08:41:10

ArrayListSubList場景

2017-06-16 16:16:36

庫存扣減查詢

2018-06-26 15:00:24

Docker安全風(fēng)險

2022-08-10 11:02:56

Python單例模式

2022-05-23 07:35:15

單例模式懶漢模式靜態(tài)內(nèi)部類

2019-12-09 10:13:20

HashMap選擇容量

2017-03-07 17:45:42

Windows磁盤碎片整理

2023-07-26 00:32:33

注解抽象spring

2013-01-15 09:41:45

編程語言

2022-07-26 23:43:29

編程語言開發(fā)Java

2021-01-14 05:08:44

編譯鏈接

2017-12-21 19:38:50

潤乾中間表
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 免费一区二区三区 | 综合久久av | 欧美日韩在线一区二区 | 99九九视频 | 精品国产乱码久久久久久蜜柚 | 亚洲美女av网站 | 亚洲第一网站 | 成人aaa视频| 91在线一区 | 国产日韩欧美二区 | 男女午夜免费视频 | 日韩成人在线网址 | 午夜电影福利 | 国产成人精品一区二三区在线观看 | 一级黄在线观看 | 成人精品一区二区 | 日韩成人免费中文字幕 | 日韩第一区 | 久久午夜国产精品www忘忧草 | 午夜午夜精品一区二区三区文 | 久久久久久一区 | 久久久做 | 午夜精品久久久 | 欧美大片黄 | 91成人免费| 黄网站涩免费蜜桃网站 | 99精品网 | 国产在线观看福利 | 国产精品日日做人人爱 | 成人欧美日韩一区二区三区 | 久久高清| 99精品国产一区二区三区 | 在线看亚洲 | 久久久久国产 | 国产欧美久久一区二区三区 | 一区二区中文字幕 | 国产激情综合五月久久 | 国产在线看片 | 亚洲精品视频在线看 | 久久免费观看视频 | 精品视频一区二区三区 |