欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中單例模式詳解

 更新時(shí)間:2016年11月09日 17:22:32   作者:會(huì)飛的小祥  
這篇文章主要介紹了Java中單例模式詳解,單例模式包括了懶漢式單例、餓漢式單例、登記式單例三種,想要了解的朋友可以了解一下。

單例模式概念:

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

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

1、單例類(lèi)只能有一個(gè)實(shí)例。

2、單例類(lèi)必須自己自己創(chuàng)建自己的唯一實(shí)例。

3、單例類(lèi)必須給所有其他對(duì)象提供這一實(shí)例。

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

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

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

public class TestStream {
   private String name;
   public String getName() {
     return name;
   }
   public void setName(String name) {
     this.name = name;
   } 
   //該類(lèi)只能有一個(gè)實(shí)例
   private TestStream(){}  //私有無(wú)參構(gòu)造方法
   //該類(lèi)必須自行創(chuàng)建
   //有2種方式
   /*private static final TestStream ts=new TestStream();*/
   private static TestStream ts1=null;
   //這個(gè)類(lèi)必須自動(dòng)向整個(gè)系統(tǒng)提供這個(gè)實(shí)例對(duì)象
   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)建的是同一個(gè)實(shí)例");
    }else if(s!=s1){
       System.out.println("創(chuàng)建的不是同一個(gè)實(shí)例");
     }else{
       System.out.println("application error");
     }
   }
 }

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

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

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

1.餓漢式單例類(lèi)

//餓漢式單例類(lèi).在類(lèi)初始化時(shí),已經(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.懶漢式單例類(lèi)

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

 3.登記式單例類(lèi)

 import java.util.HashMap;
 import java.util.Map;
 //登記式單例類(lèi).
 //類(lèi)似Spring里面的方法,將類(lèi)名注冊(cè),下次從里面直接獲取。
 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)工廠方法,返還此類(lè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);
   }
   //一個(gè)示意性的商業(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());
   }
 }

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

相關(guān)文章

  • hadoop 詳解如何實(shí)現(xiàn)數(shù)據(jù)排序

    hadoop 詳解如何實(shí)現(xiàn)數(shù)據(jù)排序

    在很多業(yè)務(wù)場(chǎng)景下,需要對(duì)原始的數(shù)據(jù)讀取分析后,將輸出的結(jié)果按照指定的業(yè)務(wù)字段進(jìn)行排序輸出,方便上層應(yīng)用對(duì)結(jié)果數(shù)據(jù)進(jìn)行展示或使用,減少二次排序的成本
    2022-02-02
  • 淺析java中static的用法

    淺析java中static的用法

    這篇文章主要介紹了java中static的用法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • SpringMVC后端返回?cái)?shù)據(jù)到前端代碼示例

    SpringMVC后端返回?cái)?shù)據(jù)到前端代碼示例

    這篇文章主要介紹了SpringMVC后端返回?cái)?shù)據(jù)到前端代碼示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 使用IDEA如何把Java程序打包成jar

    使用IDEA如何把Java程序打包成jar

    這篇文章主要介紹了使用IDEA把Java程序打包成jar,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • java保證一個(gè)方法只能執(zhí)行一次的問(wèn)題

    java保證一個(gè)方法只能執(zhí)行一次的問(wèn)題

    這篇文章主要介紹了java保證一個(gè)方法只能執(zhí)行一次的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • JAVA_基本LDAP操作實(shí)例

    JAVA_基本LDAP操作實(shí)例

    這篇文章介紹了JAVA_基本LDAP操作實(shí)例,有需要的朋友可以參考一下
    2013-09-09
  • java8 實(shí)現(xiàn)map以value值排序操作

    java8 實(shí)現(xiàn)map以value值排序操作

    這篇文章主要介紹了java8 實(shí)現(xiàn)map以value值排序操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • springboot+maven多環(huán)境動(dòng)態(tài)配置及編譯失敗的解決方案(步驟詳解)

    springboot+maven多環(huán)境動(dòng)態(tài)配置及編譯失敗的解決方案(步驟詳解)

    這篇文章主要介紹了springboot+maven多環(huán)境動(dòng)態(tài)配置及編譯失敗的解決方案,本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-11-11
  • 微信公眾平臺(tái)(測(cè)試接口)準(zhǔn)備工作

    微信公眾平臺(tái)(測(cè)試接口)準(zhǔn)備工作

    想要微信開(kāi)發(fā),首先要有個(gè)服務(wù)器,但是自己沒(méi)有。這時(shí)候可以用花生殼,將內(nèi)網(wǎng)映射到公網(wǎng)上,這樣就可以在公網(wǎng)訪問(wèn)自己的網(wǎng)站了。
    2016-05-05
  • springMvc請(qǐng)求的跳轉(zhuǎn)和傳值的方法

    springMvc請(qǐng)求的跳轉(zhuǎn)和傳值的方法

    本篇文章主要介紹了springMvc請(qǐng)求的跳轉(zhuǎn)和傳值的方法,這里整理了幾種跳轉(zhuǎn)方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-02-02

最新評(píng)論