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

Java單例模式的知識(shí)點(diǎn)詳解

 更新時(shí)間:2020年02月19日 15:59:19   作者:盛夏群島  
在本篇文章里小編給大家整理的是關(guān)于Java單例模式的知識(shí)點(diǎn)詳解,有興趣的朋友們可以學(xué)習(xí)參考下。

懶漢模式與餓漢模式

懶漢模式就是懶加載,用到的時(shí)候去加載,存在線程安全問(wèn)題,需要手動(dòng)地加鎖控制。它的優(yōu)點(diǎn)是類加載的速度比較快,按需加載,節(jié)省資源。

餓漢模式就是在類加載的時(shí)候會(huì)創(chuàng)建出實(shí)例。它天生就不存在線程安全問(wèn)題。但是類加載的速度會(huì)變慢且耗費(fèi)資源。

懶漢模式-單重檢查

示例代碼如下:

public class LazySingleton {

  private static LazySingleton singletoninstance = null;
  private Object data = new Object();

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

  }
//加鎖訪問(wèn)
  public static synchronized LazySingleton getInstance(){

    if(singletoninstance == null){
      singletoninstance = new LazySingleton();
    }
    return singletoninstance;
  }

  public Object getData() {
    return data;
  }

  public void setData(Object data) {
    this.data = data;
  }
}

測(cè)試代碼如下:

public class TestThread extends Thread {

  @Override
  public void run() {

    LazySingleton instance = LazySingleton.getInstance();
    System.out.println(instance.getData());
  }
}

public static void main(String[] args) {

    for(int i =0;i < 10;i++){
      TestThread t = new TestThread();
      t.start();
    }
  }
}

運(yùn)行結(jié)果如下:

java.lang.Object@306d3b64
java.lang.Object@306d3b64
java.lang.Object@306d3b64
java.lang.Object@306d3b64
java.lang.Object@306d3b64
java.lang.Object@306d3b64
java.lang.Object@306d3b64
java.lang.Object@306d3b64
java.lang.Object@306d3b64
java.lang.Object@306d3b64

打印出同一個(gè)object對(duì)象,表明是從同一個(gè)LazySingleton對(duì)象中獲取的數(shù)據(jù)。

但是上述代碼存在一個(gè)顯著的問(wèn)題:多個(gè)線程同時(shí)訪問(wèn)getInstance()方法都是排隊(duì)式的,即使該instance已經(jīng)被創(chuàng)建的情況下。然而,如果該instance已經(jīng)被創(chuàng)建,是可以支持并發(fā)訪問(wèn)的。需要對(duì)鎖的控制細(xì)粒度化。

懶漢模式-雙重檢查

public class LazySingleton {
//聲明為volatile變量
  private static volatile LazySingleton singletoninstance = null;
  private Object data = new Object();

  private LazySingleton(){

  }

  public static synchronized LazySingleton getInstance(){

    if(singletoninstance == null){
      synchronized (LazySingleton.class) {
        //這個(gè)第二重的的檢查是必要的
        if(singletoninstance == null)
          singletoninstance = new LazySingleton();
      }
    }
    return singletoninstance;
  }

  public Object getData() {
    return data;
  }

  public void setData(Object data) {
    this.data = data;
  }
}

第二重檢查是為了防止:

線程A發(fā)現(xiàn)instance未被創(chuàng)建,于是申請(qǐng)鎖,進(jìn)入臨界區(qū)創(chuàng)建instance;于此同時(shí)另一個(gè)線程也發(fā)現(xiàn)instance未被創(chuàng)建,于是也要申請(qǐng)鎖去創(chuàng)建instance,問(wèn)題就這樣發(fā)生了。而且,這個(gè)instance變量要被聲明為volatile,也就是其中一個(gè)線程對(duì)它就行修改之后(也就是實(shí)例化),這一修改立馬對(duì)其他線程可見(jiàn),避免了無(wú)謂的等待。

檢查代碼同上,運(yùn)行結(jié)果同上。

餓漢模式

public class HungerSingleton {

  private static final HungerSingleton singletoninstance = new HungerSingleton();
  private Object data = new Object();

  private HungerSingleton(){

  }

  public static HungerSingleton getInstance(){

    return singletoninstance;
  }

  public Object getData() {
    return data;
  }

  public void setData(Object data) {
    this.data = data;
  }

}

在加載該類的時(shí)候就立馬去實(shí)例化instance,不存在線程安全問(wèn)題(由jvm保證線程安全問(wèn)題),但是存在資源浪費(fèi)、加載速度慢的問(wèn)題。

檢查代碼同上,運(yùn)行結(jié)果同上。

Holder模式

就是利用一個(gè)靜態(tài)內(nèi)部類來(lái)實(shí)現(xiàn)instance的實(shí)例化。這里利用了靜態(tài)內(nèi)部類的一個(gè)特性:該內(nèi)部類的實(shí)例與外部類的實(shí)例 沒(méi)有綁定關(guān)系,而且只有被調(diào)用到才會(huì)裝載,從而實(shí)現(xiàn)了延遲加載

public class HolderSingleton {

  private Object data = new Object();

  private HolderSingleton(){

  }
  
  private static class InnerClass{

    private static HolderSingleton singletoninstance = new HolderSingleton();
  }

  public static HolderSingleton getInstance(){

    return InnerClass.singletoninstance;
  }

  public Object getData() {
    return data;
  }

  public void setData(Object data) {
    this.data = data;
  }
}

測(cè)試代碼同上,運(yùn)行結(jié)果同上。

在加載InnerClass的時(shí)候才會(huì)去實(shí)例化這個(gè)instance,實(shí)現(xiàn)了延遲加載,并且同餓漢模式一樣,由jvm保證線程安全。這種方法值得推薦。

應(yīng)用場(chǎng)景:

在整個(gè)系統(tǒng)中,只允許共用一個(gè)實(shí)例的類適合用單例模式來(lái)實(shí)現(xiàn),比如:

網(wǎng)站的計(jì)數(shù)器,只允許存在一個(gè)計(jì)數(shù)器實(shí)例;

線程池,只允許存在一個(gè)線程池對(duì)象;

連接池,只允許存在一個(gè)連接池對(duì)象;

知識(shí)點(diǎn)擴(kuò)充

1.為什么要使用單例模式?

在我們?nèi)粘5墓ぷ髦校芏鄬?duì)象通常占用非常重要的系統(tǒng)資源,比如:IO處理,數(shù)據(jù)庫(kù)操作等,那我們必須要限制這些對(duì)象只有且始終使用一個(gè)公用的實(shí)例,即單例。

2.單例模式的實(shí)現(xiàn)方式

構(gòu)造函數(shù)私有化,防止其他類生成唯一公用實(shí)例外的實(shí)例。且單例類應(yīng)該被定義為final,也就是說(shuō)單例類不能被繼承,因?yàn)槿绻试S繼承那子類就都可以創(chuàng)建實(shí)例,違背了類唯一實(shí)例的初衷。

類中一個(gè)靜態(tài)變量來(lái)保存單實(shí)例的引用。

一個(gè)共有的靜態(tài)方法來(lái)獲取單實(shí)例的引用。
3.單例模式的UML類圖

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

  • 餓漢式:一開(kāi)始就創(chuàng)建好實(shí)例,每次調(diào)用直接返回,經(jīng)典的“拿空間換時(shí)間”。
  • 懶漢式:延遲加載,第一次調(diào)用的時(shí)候才加載,然后返回,以后的每次的調(diào)用就直接返回。經(jīng)典“拿時(shí)間換空間”,多線程環(huán)境下要注意解決線程安全的問(wèn)題。
  • 登記式:對(duì)一組單例模式進(jìn)行的維護(hù),主要是在數(shù)量上的擴(kuò)展,通過(guò)線程安全的map把單例存進(jìn)去,這樣在調(diào)用時(shí),先判斷該單例是否已經(jīng)創(chuàng)建,是的話直接返回,不是的話創(chuàng)建一個(gè)登記到map中,再返回。

以上就是本次腳本之家小編結(jié)合多篇整理的相關(guān)內(nèi)容,希望能夠幫助到大家。

相關(guān)文章

  • java線程間通信的通俗解釋及代碼示例

    java線程間通信的通俗解釋及代碼示例

    這篇文章主要介紹了java線程間通信的通俗解釋,介紹了線程通信中的幾個(gè)相關(guān)概念,然后分享了線程通信的實(shí)現(xiàn)方式及代碼示例,具有一定參考價(jià)值 ,需要的朋友可以了解下。
    2017-11-11
  • java maven中如何引入自己的lib

    java maven中如何引入自己的lib

    在JavaMaven項(xiàng)目中引入自己的庫(kù)可以簡(jiǎn)化為幾個(gè)步驟:首先,確保庫(kù)以JAR格式存在或打包成JAR;其次,將JAR文件放置在項(xiàng)目目錄或安裝到本地Maven倉(cāng)庫(kù);最后,在pom.xml中添加依賴,這樣做可以使項(xiàng)目更加模塊化,便于管理和維護(hù),感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • springboot項(xiàng)目連接多種數(shù)據(jù)庫(kù)該如何操作詳析

    springboot項(xiàng)目連接多種數(shù)據(jù)庫(kù)該如何操作詳析

    在Spring Boot應(yīng)用中連接多個(gè)數(shù)據(jù)庫(kù)或數(shù)據(jù)源可以使用多種方式,下面這篇文章主要給大家介紹了關(guān)于springboot項(xiàng)目連接多種數(shù)據(jù)庫(kù)該如何操作的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08
  • Maven模版Bug及解決辦法

    Maven模版Bug及解決辦法

    默認(rèn),會(huì)幫我們創(chuàng)建src/main/resources 按照Maven的規(guī)范,Maven會(huì)有3個(gè)目錄,分別是: src/main/java : java源文件存放位置 src/main/resource : resource資源,如配置文件等 src/test/java : 測(cè)試代碼源文件存放位置
    2016-04-04
  • Java RPC框架熔斷降級(jí)機(jī)制原理解析

    Java RPC框架熔斷降級(jí)機(jī)制原理解析

    這篇文章主要介紹了Java RPC框架熔斷降級(jí)機(jī)制原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Java基礎(chǔ)第五篇 實(shí)施接口

    Java基礎(chǔ)第五篇 實(shí)施接口

    在public和private的封裝機(jī)制,我們實(shí)際上同時(shí)定義了類和接口,類和接口混合在一起。Java還提供了interface這一語(yǔ)法。這一語(yǔ)法將接口從類的具體定義中剝離出來(lái),構(gòu)成一個(gè)獨(dú)立的主體,下面文章內(nèi)容將為大家做詳細(xì)介紹
    2021-09-09
  • 利用javaFX實(shí)現(xiàn)移動(dòng)一個(gè)小球的示例代碼

    利用javaFX實(shí)現(xiàn)移動(dòng)一個(gè)小球的示例代碼

    這篇文章主要介紹了利用javaFX實(shí)現(xiàn)移動(dòng)一個(gè)小球的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • MyBatis-Plus?條件查詢器的實(shí)現(xiàn)

    MyBatis-Plus?條件查詢器的實(shí)現(xiàn)

    本文主要介紹了MyBatis-Plus?條件查詢器的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Spring Boot @Conditional注解用法示例介紹

    Spring Boot @Conditional注解用法示例介紹

    這篇文章主要給大家介紹了關(guān)于Spring Boot @Conditional注解用法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • SpringBoot的兩種啟動(dòng)方式原理解析(配置方案)

    SpringBoot的兩種啟動(dòng)方式原理解析(配置方案)

    本文介紹了Spring?Boot中兩種啟動(dòng)方式,使用內(nèi)置Tomcat啟動(dòng)和使用外置Tomcat部署,在使用內(nèi)置Tomcat啟動(dòng)時(shí),可以通過(guò)IDEA的main函數(shù)啟動(dòng),也可以使用nohup命令在后臺(tái)運(yùn)行,這篇文章主要介紹了SpringBoot的兩種啟動(dòng)方式原理?,需要的朋友可以參考下
    2025-01-01

最新評(píng)論

喀喇沁旗| 锦屏县| 方正县| 汉沽区| 连州市| 沧源| 华容县| 玉林市| 阳泉市| 林州市| 贵定县| 渭南市| 宽城| 于都县| 开阳县| 灵山县| 醴陵市| 永泰县| 宣城市| 济阳县| 南城县| 泰州市| 锡林郭勒盟| 崇仁县| 盱眙县| 建水县| 浦北县| 河北区| 蓬安县| 宁波市| 呈贡县| 明水县| 青川县| 宁河县| 利津县| 宜良县| 二连浩特市| 天峨县| 大名县| 嘉兴市| 东海县|