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

java 單例模式的實(shí)例詳解

 更新時間:2017年10月15日 11:23:27   投稿:lqh  
這篇文章主要介紹了java 單例模式的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助大家徹底理解掌握這部分內(nèi)容,需要的朋友可以參考下

java 單例模式的實(shí)例詳解

概念:   

java中單例模式是一種常見的設(shè)計(jì)模式,單例模式分三種:懶漢式單例、餓漢式單例、登記式單例三種。   

單例模式有一下特點(diǎn):

  1、單例類只能有一個實(shí)例。
  2、單例類必須自己自己創(chuàng)建自己的唯一實(shí)例。
  3、單例類必須給所有其他對象提供這一實(shí)例。   

單例模式確保某個類只有一個實(shí)例,而且自行實(shí)例化并向整個系統(tǒng)提供這個實(shí)例。在計(jì)算機(jī)系統(tǒng)中,線程池、緩存、日志對象、對話框、打印機(jī)、顯卡的驅(qū)動程序?qū)ο蟪1辉O(shè)計(jì)成單例。這些應(yīng)用都或多或少具有資源管理器的功能。每臺計(jì)算機(jī)可以有若干個打印機(jī),但只能有一個Printer Spooler,以避免兩個打印作業(yè)同時輸出到打印機(jī)中。每臺計(jì)算機(jī)可以有若干通信端口,系統(tǒng)應(yīng)當(dāng)集中管理這些通信端口,以避免一個通信端口同時被兩個請求同時調(diào)用。總之,選擇單例模式就是為了避免不一致狀態(tài),避免政出多頭。

首先看一個經(jīng)典的單例實(shí)現(xiàn)。

public class Singleton {
  private static Singleton uniqueInstance = null;

  private Singleton() {
    // Exists only to defeat instantiation.
  }

  public static Singleton getInstance() {
    if (uniqueInstance == null) {
      uniqueInstance = new Singleton();
    }
    return uniqueInstance;
  }
  // Other methods...
}

Singleton通過將構(gòu)造方法限定為private避免了類在外部被實(shí)例化,在同一個虛擬機(jī)范圍內(nèi),Singleton的唯一實(shí)例只能通過getInstance()方法訪問。(事實(shí)上,通過Java反射機(jī)制是能夠?qū)嵗瘶?gòu)造方法為private的類的,那基本上會使所有的Java單例實(shí)現(xiàn)失效。此問題在此處不做討論,姑且掩耳盜鈴地認(rèn)為反射機(jī)制不存在。)

但是以上實(shí)現(xiàn)沒有考慮線程安全問題。所謂線程安全是指:如果你的代碼所在的進(jìn)程中有多個線程在同時運(yùn)行,而這些線程可能會同時運(yùn)行這段代碼。如果每次運(yùn)行結(jié)果和單線程運(yùn)行的結(jié)果是一樣的,而且其他的變量的值也和預(yù)期的是一樣的,就是線程安全的?;蛘哒f:一個類或者程序所提供的接口對于線程來說是原子操作或者多個線程之間的切換不會導(dǎo)致該接口的執(zhí)行結(jié)果存在二義性,也就是說我們不用考慮同步的問題。顯然以上實(shí)現(xiàn)并不滿足線程安全的要求,在并發(fā)環(huán)境下很可能出現(xiàn)多個Singleton實(shí)例。

public class TestStream {
  private String name;
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  } 
  //該類只能有一個實(shí)例
  private TestStream(){}  //私有無參構(gòu)造方法
  //該類必須自行創(chuàng)建
  //有2種方式
  /*private static final TestStream ts=new TestStream();*/
  private static TestStream ts1=null;
  //這個類必須自動向整個系統(tǒng)提供這個實(shí)例對象
  public static TestStream getTest(){
    if(ts1==null){
      ts1=new TestStream();
    }
    return ts1;
  }
  public void getInfo(){
    System.out.println("output message "+name);
  }
}
/**
 * 
 */
public class TestMain {
  public static void main(String [] args){
    TestStream s=TestStream.getTest();
    s.setName("張孝祥");
    System.out.println(s.getName());
    TestStream s1=TestStream.getTest();
    s1.setName("張孝祥");
    System.out.println(s1.getName());
    s.getInfo();
    s1.getInfo();
    if(s==s1){
      System.out.println("創(chuàng)建的是同一個實(shí)例");
    }else if(s!=s1){
      System.out.println("創(chuàng)建的不是同一個實(shí)例");
    }else{
      System.out.println("application error");
    }
  }
}

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

張孝祥
張孝祥
output message 張孝祥
output message 張孝祥
創(chuàng)建的是同一個實(shí)例

結(jié)論:由結(jié)果可以得知單例模式為一個面向?qū)ο蟮膽?yīng)用程序提供了對象惟一的訪問點(diǎn),不管它實(shí)現(xiàn)何種功能,整個應(yīng)用程序都會同享一個實(shí)例對象。

1.餓漢式單例類

//餓漢式單例類.在類初始化時,已經(jīng)自行實(shí)例化 
public class Singleton1 {
  //私有的默認(rèn)構(gòu)造子
  private Singleton1() {}
  //已經(jīng)自行實(shí)例化 
  private static final Singleton1 single = new Singleton1();
  //靜態(tài)工廠方法 
  public static Singleton1 getInstance() {
    return single;
  }
}

2.懶漢式單例類

//懶漢式單例類.在第一次調(diào)用的時候?qū)嵗?
public class Singleton2 {
  //私有的默認(rèn)構(gòu)造子
  private Singleton2() {}
  //注意,這里沒有final  
  private static Singleton2 single=null;
  //靜態(tài)工廠方法 
  public synchronized static Singleton2 getInstance() {
     if (single == null) { 
       single = new Singleton2();
     } 
    return single;
  }
}

3.登記式單例類

import java.util.HashMap;
import java.util.Map;
//登記式單例類.
//類似Spring里面的方法,將類名注冊,下次從里面直接獲取。
public class Singleton3 {
  private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();
  static{
    Singleton3 single = new Singleton3();
    map.put(single.getClass().getName(), single);
  }
  //保護(hù)的默認(rèn)構(gòu)造子
  protected Singleton3(){}
  //靜態(tài)工廠方法,返還此類惟一的實(shí)例
  public static Singleton3 getInstance(String name) {
    if(name == null) {
      name = Singleton3.class.getName();
      System.out.println("name == null"+"--->name="+name);
    }
    if(map.get(name) == null) {
      try {
        map.put(name, (Singleton3) Class.forName(name).newInstance());
      } catch (InstantiationException e) {
        e.printStackTrace();
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      }
    }
    return map.get(name);
  }
  //一個示意性的商業(yè)方法
  public String about() {  
    return "Hello, I am RegSingleton.";  
  }  
  public static void main(String[] args) {
    Singleton3 single3 = Singleton3.getInstance(null);
    System.out.println(single3.about());
  }
}

如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關(guān)文章

  • Java中的內(nèi)存泄露問題和解決辦法

    Java中的內(nèi)存泄露問題和解決辦法

    大家好,本篇文章主要講的是Java中的內(nèi)存泄露問題和解決辦法,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • Java中的@Async異步功能詳解

    Java中的@Async異步功能詳解

    這篇文章主要介紹了Java中的@Async異步功能詳解,@Async注解,可以實(shí)現(xiàn)異步處理的功能,它可以有返回值,或者直接在新線程時并行執(zhí)行一個任務(wù),對于異步來說,它的執(zhí)行是有條件的,你需要把異步代碼塊放在單獨(dú)的類里,需要的朋友可以參考下
    2023-11-11
  • Springboot 2.x集成kafka 2.2.0的示例代碼

    Springboot 2.x集成kafka 2.2.0的示例代碼

    kafka近幾年更新非??欤部梢钥闯鰇afka在企業(yè)中是用的頻率越來越高。本文主要為大家介紹了Springboot 2.x集成kafka 2.2.0的示例代碼,需要的可以參考一下
    2022-04-04
  • Java獲取請求頭信息的操作步驟

    Java獲取請求頭信息的操作步驟

    這篇文章主要介紹了Java獲取請求頭信息,本文分步驟結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • 注解、原生Spring、SchemaBased三種方式實(shí)現(xiàn)AOP代碼案例

    注解、原生Spring、SchemaBased三種方式實(shí)現(xiàn)AOP代碼案例

    這篇文章主要介紹了注解、原生Spring、SchemaBased三種方式實(shí)現(xiàn)AOP的方法介紹,文中有詳細(xì)的代碼示例,對我們的學(xué)習(xí)有一定的幫助,需要的朋友可以參考下
    2023-06-06
  • 基于LinkedHashMap實(shí)現(xiàn)LRU緩存

    基于LinkedHashMap實(shí)現(xiàn)LRU緩存

    LinkedHashMap是Java集合中一個常用的容器,它繼承了HashMap, 是一個有序的Hash表。那么該如何基于LinkedHashMap實(shí)現(xiàn)一個LRU緩存呢?本文將介紹LinkedHashMap的實(shí)現(xiàn)原理,感興趣的同學(xué)可以參考一下
    2023-05-05
  • SpringBoot中Mybatis + Druid 數(shù)據(jù)訪問的詳細(xì)過程

    SpringBoot中Mybatis + Druid 數(shù)據(jù)訪問的詳細(xì)過程

    Spring Boot 底層都是采用 SpringData 的方式進(jìn)行統(tǒng)一處理各種數(shù)據(jù)庫,SpringData也是Spring中與SpringBoot、SpringCloud 等齊名的知名項(xiàng)目,下面看下SpringBoot Mybatis Druid數(shù)據(jù)訪問的詳細(xì)過程,感興趣的朋友一起看看吧
    2021-11-11
  • springboot?ConfigurationProperties的綁定源碼示例解析

    springboot?ConfigurationProperties的綁定源碼示例解析

    這篇文章主要為大家介紹了springboot?ConfigurationProperties的綁定源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Java線程間協(xié)作wait、notify和notifyAll詳解

    Java線程間協(xié)作wait、notify和notifyAll詳解

    這篇文章主要介紹了Java線程間協(xié)作wait、notify和notifyAll詳解,在 Java 中可以用 wait、notify 和 notifyAll 來實(shí)現(xiàn)線程間的通信,盡管關(guān)于wait和notify的概念很基礎(chǔ),它們也都是Object類的函數(shù),但用它們來寫代碼卻并不簡單,,需要的朋友可以參考下
    2023-10-10
  • MyBatis SpringMVC整合實(shí)現(xiàn)步驟詳解

    MyBatis SpringMVC整合實(shí)現(xiàn)步驟詳解

    這篇文章主要介紹了MyBatis SpringMVC整合實(shí)現(xiàn)步驟詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-08-08

最新評論

义马市| 唐海县| 石渠县| 太湖县| 寻甸| 乌拉特中旗| 庆城县| 阜阳市| 建湖县| 曲沃县| 铁岭县| 东安县| 全椒县| 鱼台县| 陆河县| 夹江县| 永善县| 福海县| 玛纳斯县| 靖江市| 泊头市| 长兴县| 炎陵县| 故城县| 湘潭县| 罗源县| 芜湖县| 鄂尔多斯市| 迭部县| 万州区| 贵定县| 万全县| 临夏市| 曲麻莱县| 法库县| 绥阳县| 长武县| 东安县| 融水| 论坛| 乌兰县|