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

Java設(shè)計模式單例模式(Singleton)用法解析

 更新時間:2019年11月18日 14:33:43   作者:brucegan  
這篇文章主要介紹了Java設(shè)計模式單例模式(Singleton)用法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

這篇文章主要介紹了Java設(shè)計模式單例模式(Singleton)用法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

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

  單例模式(Singleton Pattern)是指確保一個類在任何情況下都絕對只有一個實例。并提供一個全局反訪問點。單例模式是創(chuàng)建型模式。單例模式在生活中應(yīng)用也很廣泛,比如公司CEO只有一個,部門經(jīng)理只有一個等。JAVA中ServletCOntext,ServetContextCOnfig等,還有spring中ApplicationContext應(yīng)用上下文對象,SessionFactory,數(shù)據(jù)庫連接池對象等。使用單例模式可以將其常駐于內(nèi)存,可以節(jié)約更多資源。

寫法:

  1:懶漢模式(線程不安全)

/**
 * 線程不安全的懶漢式單利模式
 * 
 * Created by gan on 2019/11/17 17:33.
 */
public class LazySingleton {
  private static LazySingleton instance;

  //構(gòu)造方法私有化
  private LazySingleton() {
  }

  public static LazySingleton getInstance() {
    if (instance != null) {
      instance = new LazySingleton();
    }
    return instance;
  }
}

  上面的代碼,提供一個靜態(tài)對象instance,構(gòu)造函數(shù)私有化防止外部創(chuàng)建對象,提供一個靜態(tài)的getInstance方法來給訪問者一個單例對象。這種寫法的缺點就是沒有考慮到線程安全問題,當(dāng)多個訪問者同時訪問的時候很有可能創(chuàng)建多個對象。之所以叫懶漢式,是因為這種寫法是使用的時候才創(chuàng)建,起到了懶加載Lazy loading的作用,實際開發(fā)中不建議采用這種寫法。

  2:線程安全的懶漢式(加鎖)

/**
 * 線程安全的懶漢式單利模式
 * 
 * Created by gan on 2019/11/17 17:33.
 */
public class LazySingleton {
  private static LazySingleton instance;

  //構(gòu)造方法私有化
  private LazySingleton() {
  }

  public synchronized static LazySingleton getInstance() {
    if (instance != null) {
      instance = new LazySingleton();
    }
    return instance;
  }
}

  這種寫法就是在第一種的基礎(chǔ)上添加了synchronized關(guān)鍵字保證了線程安全。這種寫法在并發(fā)高的時候雖然保證了線程安全,但是效率很低,高并發(fā)的時候所有訪問的線程都要排隊等待,所以實際開發(fā)中也不建議采用。

  3:惡漢式(線程安全)

/**
 * 餓漢式(線程安全)
 * Created by gan on 2019/10/28 22:52.
 */
public class HungrySigleton {

  public static final HungrySigleton instance = new HungrySigleton();

  private HungrySigleton(){}

  public static HungrySigleton getInstance(){
    return instance;
  }
}

  直接在運行(加載)這個類的時候創(chuàng)建了對象,之后直接訪問。顯然這種方式?jīng)]有起到Lazy loading的效果。但是是線程安全的,實際開發(fā)中還是比較常用。

  4:靜態(tài)內(nèi)部類(線程安全)

/**
 * 靜態(tài)內(nèi)部類方式
 * Created by gan on 2019/11/17 17:46.
 */
public class StaticInnerClassSingleton {

  //構(gòu)造方法私有化
  private StaticInnerClassSingleton() {}

  //內(nèi)部類
  private static class HolderInnerClass {
    //需要提供單利對象的外部類作為靜態(tài)屬性加載的時候就初始化
    private static StaticInnerClassSingleton instance = new StaticInnerClassSingleton();
  }

  //對外暴漏訪問點
  public static StaticInnerClassSingleton getInstance() {
    return HolderInnerClass.instance;
  }
}

  這種內(nèi)部類跟餓漢式單例有很多相似的地方,相比餓漢式單例模式的區(qū)別也是好處在于:靜態(tài)內(nèi)部類不在單例類加載時就加載,而是在調(diào)用getInstance()方法的時候才進(jìn)行加載,達(dá)到了類似于懶漢式的效果,而且這種方法又是線程安全的。實際開發(fā)中也建議采用。

  5:枚舉方法單例(線程安全)

/**
 * 枚舉單利模式
 * Created by gan on 2019/11/17 17:57.
 */
public enum EnumSingleton {
  INSTANCE;

  public void otherMetthod() {
    System.out.println("需要單利對象調(diào)用的方法。。。");
  }
}

  Effective Java作者Josh Bloch提倡的方式,好處有如下:

  1:自由串行化。

  2:保證了一個實例

  3:線程安全

  這種方式防止了單例模式被破壞,而且簡潔寫法簡單,而且絕對的線程安全,但是有個缺點就是不能繼承。

  6:雙重檢查法(通常線程安全,低概率不安全)

/**
 * Double check
 * Created by gan on 2019/11/17 18:03.
 */
public class DoubleCheckSingleton {
  private static DoubleCheckSingleton instance;

  private DoubleCheckSingleton() {}

  public static DoubleCheckSingleton getInstance() {
    if (instance == null) {
      synchronized (DoubleCheckSingleton.class) {
        if (instance == null) {
          instance = new DoubleCheckSingleton();
        }
      }
    }
    return instance;
  }
}

  上面的這種寫法在并發(fā)極高的時候也可能會出現(xiàn)問題(當(dāng)然這種概率非常小,但是畢竟還是有的嘛),解決的方案就是給instance的聲明加上volatile關(guān)鍵字即可。于是就出現(xiàn)了下面第7總寫法。

  7:Double check(volatile)

/**
 * Double check volatile
 * Created by gan on 2019/11/17 18:03.
 */
public class DoubleCheckSingleton {
  private volatile static DoubleCheckSingleton instance;

  private DoubleCheckSingleton() {}

  public static DoubleCheckSingleton getInstance() {
    if (instance == null) {
      synchronized (DoubleCheckSingleton.class) {
        if (instance == null) {
          instance = new DoubleCheckSingleton();
        }
      }
    }
    return instance;
  }
}

volatile關(guān)鍵字的其中一個作用就是禁止指令重排序,把instance聲明volatile后,對它的操作就會有一個內(nèi)存屏障(什么是內(nèi)存屏障?),這樣在賦值完成之前,就不會調(diào)用讀操作。這里具體的原因網(wǎng)上也是眾說紛紜,這里不進(jìn)行具體闡述。

  8:ThreadLocal實現(xiàn)單例模式(線程安全)

/**
 * ThreadLocal實現(xiàn)單利模式
 * Created by gan on 2019/11/17 18:17.
 */
public class ThreadLocalSingleton {

  private static final ThreadLocal<ThreadLocalSingleton> threadLocal = new ThreadLocal() {
    @Override
    protected ThreadLocalSingleton initialValue() {
      return new ThreadLocalSingleton();
    }
  };

  private ThreadLocalSingleton(){}

  public static ThreadLocalSingleton getInstance(){
    return threadLocal.get();
  }
}

  ThreadLocal會為每個線程提供一個獨立的變量副本,從而隔離了多個線程堆數(shù)據(jù)的訪問沖突。對于多線程資源共享問題,同步機(jī)制采用了“以時間換空間”的方式,而ThreadLocal則采用了“以空間換時間”的方式(主要就是避免了加鎖排隊)。 前者提供一份變量,讓不同的線程排隊訪問,而后者為每一個線程提供了一份變量,因此可以同時訪問而互不影響。但是實際是創(chuàng)建了多個單例對象的。

單例模式的破壞:

  1:序列化破壞

    一個對象創(chuàng)建好以后,有時候需要將對象序列化然后寫入磁盤。下次在從磁盤中讀取并反序列化,將其轉(zhuǎn)化為內(nèi)存對象。反序列化后的對象會重新分配內(nèi)存,即創(chuàng)建型的對象。這樣就違背了單例模式的初衷。解決這種方式的方法就是在單例類中新增一個 private Object readResolve();方法即可,具體原因可以看看序列化和反序列化的源碼。

  2:反射

    通過反射“暴力破解”也能破壞單例模式,具體暫時不闡述。

  3:克隆

    克隆也會破壞單例模式,具體暫時不闡述。

代碼鏈接:https://gitee.com/ganganbobo/gps-parent

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java Swing中的表格(JTable)和樹(JTree)組件使用實例

    Java Swing中的表格(JTable)和樹(JTree)組件使用實例

    這篇文章主要介紹了Java Swing中的表格(JTable)和樹(JTree)組件使用實例,本文同時講解了表格和樹的基本概念、常用方法、代碼實例,需要的朋友可以參考下
    2014-10-10
  • SpringBoot獲取前臺參數(shù)的六種方式以及統(tǒng)一響應(yīng)

    SpringBoot獲取前臺參數(shù)的六種方式以及統(tǒng)一響應(yīng)

    本文主要介紹了SpringBoot獲取前臺參數(shù)的六種方式以及統(tǒng)一響應(yīng),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • mybatis整合ehcache做三級緩存的實現(xiàn)方法

    mybatis整合ehcache做三級緩存的實現(xiàn)方法

    ehcache是一個快速內(nèi)存緩存框架,java項目里用起來很方便,下面這篇文章主要給大家介紹了關(guān)于mybatis整合ehcache做三級緩存的實現(xiàn)方法,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • SpringBoot中使用RocketMQ的示例代碼

    SpringBoot中使用RocketMQ的示例代碼

    本文主要介紹SpringBoot中使用RocketMQ的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • java中forward轉(zhuǎn)發(fā)的使用

    java中forward轉(zhuǎn)發(fā)的使用

    在Java中,forward轉(zhuǎn)發(fā)是一種非常常見且重要的操作,我們將深入探討forward的概念和用法,并給出一些代碼示例來幫助讀者更好地理解,感興趣的可以了解下
    2023-11-11
  • Java中反射的學(xué)習(xí)筆記分享

    Java中反射的學(xué)習(xí)筆記分享

    反射是Java編程語言中的一個特性。它允許執(zhí)行的Java程序檢查或?操作?自身,并操作程序的內(nèi)部屬性。本文將通過幾個示例帶大家詳細(xì)了解一下Java中反射的使用,需要的可以參考一下
    2022-11-11
  • Java?Map.values()方法之如何獲取Map集合中的所有鍵值對象

    Java?Map.values()方法之如何獲取Map集合中的所有鍵值對象

    這篇文章主要介紹了Java?Map.values()方法之如何獲取Map集合中的所有鍵值對象問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 教你用JDK編譯Java文件的方法

    教你用JDK編譯Java文件的方法

    這篇文章主要介紹了教你用JDK編譯Java文件的方法,分步驟給大家介紹了設(shè)置環(huán)境變量的方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-01-01
  • java微信延遲支付的實現(xiàn)示例

    java微信延遲支付的實現(xiàn)示例

    最近在面試的過程中總會出現(xiàn)一些關(guān)于微信支付延遲返回結(jié)果的處理方式的問題,本文主要介紹了java微信延遲支付的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • idea中l(wèi)ombok啟用的方法示例

    idea中l(wèi)ombok啟用的方法示例

    這篇文章主要介紹了idea中l(wèi)ombok啟用的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評論

阳江市| 新安县| 镇宁| 赫章县| 富民县| 峡江县| 芷江| 肇庆市| 上蔡县| 广元市| 珲春市| 鄂托克旗| 顺昌县| 高要市| 闻喜县| 长丰县| 东城区| 邹城市| 湘阴县| 辽阳县| 高陵县| 囊谦县| 定陶县| 泗洪县| 南川市| 松江区| 南江县| 沧源| 宁南县| 龙泉市| 华容县| 普宁市| 云林县| 临安市| 遂平县| 北安市| 新蔡县| 娄底市| 德格县| 灵山县| 万宁市|