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

Java中單例模式詳解

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

單例模式概念:

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

單例模式有一下特點:

1、單例類只能有一個實例。

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

3、單例類必須給所有其他對象提供這一實例。

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

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

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

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

運行結果:

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

結論:由結果可以得知單例模式為一個面向對象的應用程序提供了對象惟一的訪問點,不管它實現(xiàn)何種功能,整個應用程序都會同享一個實例對象。

1.餓漢式單例類

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

 2.懶漢式單例類

 //懶漢式單例類.在第一次調(diào)用的時候實例化 
 public class Singleton2 {
   //私有的默認構造子
   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);
   }
   //保護的默認構造子
   protected Singleton3(){}
   //靜態(tài)工廠方法,返還此類惟一的實例
   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());
   }
 }

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

相關文章

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

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

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

    淺析java中static的用法

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

    SpringMVC后端返回數(shù)據(jù)到前端代碼示例

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

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

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

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

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

    JAVA_基本LDAP操作實例

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

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

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

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

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

    微信公眾平臺(測試接口)準備工作

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

    springMvc請求的跳轉和傳值的方法

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

最新評論