您現在的位置是:首頁 > 運動

Java單例模式詳解

由 CSDN 發表于 運動2022-04-18
簡介這個類必須自動向整個系統提供這個例項物件 public static TestStream getTest(){ if(ts1==null){ ts1=new TestStream()

單例類怎麼寫

概念:

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

單例模式有一下特點:

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

2、單例類必須自己自己建立自己的唯一例項。

3、單例類必須給所有其他物件提供這一例項。

單例模式確保某個類只有一個例項,而且自行例項化並向整個系統提供這個例項。在計算機系統中,執行緒池、快取、日誌物件、對話方塊、印表機、顯示卡的驅動程式物件常被設計成單例。這些應用都或多或少具有資源管理器的功能。每臺計算機可以有若干個印表機,但只能有一個Printer Spooler,以避免兩個列印作業同時輸出到印表機中。每臺計算機可以有若干通訊埠,系統應當集中管理這些通訊埠,以避免一個通訊埠同時被兩個請求同時呼叫。總之,選擇單例模式就是為了避免不一致狀態,避免政出多頭。

首先看一個經典的單例實現。

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避免了類在外部被例項化,在同一個虛擬機器範圍內,Singleton的唯一例項只能透過getInstance()方法訪問。(事實上,透過Java反射機制是能夠例項化構造方法為private的類的,那基本上會使所有的Java單例實現失效。此問題在此處不做討論,姑且掩耳盜鈴地認為反射機制不存在。)

但是以上實現沒有考慮執行緒安全問題。所謂執行緒安全是指:如果你的程式碼所在的程序中有多個執行緒在同時執行,而這些執行緒可能會同時執行這段程式碼。如果每次執行結果和單執行緒執行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是執行緒安全的。或者說:一個類或者程式所提供的介面對於執行緒來說是原子操作或者多個執行緒之間的切換不會導致該介面的執行結果存在二義性,也就是說我們不用考慮同步的問題。顯然以上實現並不滿足執行緒安全的要求,在併發環境下很可能出現多個Singleton例項。

public class TestStream { private String name; public String getName() { return name; } public void setName(String name) { this。name = name; } //該類只能有一個例項 private TestStream(){} //私有無參構造方法 //該類必須自行建立 //有2種方式 /*private static final TestStream ts=new TestStream();*/ private static TestStream ts1=null; //這個類必須自動向整個系統提供這個例項物件 public static TestStream getTest(){ if(ts1==null){ ts1=new TestStream(); } return ts1; } public void getInfo(){ System。out。println(“output message ”+name); } }

/** * Java學習交流QQ群:589809992 我們一起學Java! */ 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(“建立的是同一個例項”); }else if(s!=s1){ System。out。println(“建立的不是同一個例項”); }else{ System。out。println(“application error”); } } }

執行結果:

張孝祥 張孝祥 output message 張孝祥 output message 張孝祥 建立的是同一個例項

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

1。餓漢式單例類

//餓漢式單例類。在類初始化時,已經自行例項化 public class Singleton1 { //私有的預設構造子 private Singleton1() {} //已經自行例項化 private static final Singleton1 single = new Singleton1(); //靜態工廠方法 public static Singleton1 getInstance() { return single; } }

2。懶漢式單例類

//懶漢式單例類。在第一次呼叫的時候例項化 public class Singleton2 { //私有的預設構造子 private Singleton2() {} //注意,這裡沒有final private static Singleton2 single=null; //靜態工廠方法 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 map = new HashMap(); static{ Singleton3 single = new Singleton3(); map。put(single。getClass()。getName(), single); } //保護的預設構造子 protected Singleton3(){} //靜態工廠方法,返還此類惟一的例項 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); } //一個示意性的商業方法 public String about() { return “Hello, I am RegSingleton。”; } public static void main(String[] args) { Singleton3 single3 = Singleton3。getInstance(null); System。out。println(single3。about()); } }

推薦文章

  • 1毛錢紙幣不算錢?即墨女子用毛票坐公交竟被要求投幣補票!

    2月6日,記者聯絡到即墨永昌公共交通有限公司客服人員,工作人員向相關部門落實後回覆,他們公司公交車不收一角紙幣是因為工作人員到銀行網點存不上,必須到銀行在即墨的總部換取才行...

  • 12GB+512GB+四曲面屏,跌價1260元,100倍變焦旗艦售價更親民了

    12GB+512GB+四曲面屏,跌價1260元,100倍變焦旗艦售價更親民了榮耀Magic4 Pro是榮耀公司今年的高階旗艦,作為華為曾經的子品牌,在製造高階旗艦這件事情上榮耀公司也有自己的傲氣,不願意隨便閹割配置,力求在各個方面都達到頂尖旗艦標準,也得益於這股傲氣,榮耀Magic4 Pro在今年國內的高階旗艦市場...

  • 拍照片,不會擺姿勢咋辦?來學這篇攝影教程吧

    拍照片,不會擺姿勢咋辦?來學這篇攝影教程吧站著拍照片的時候,很多人的手,無處安放,這樣就會導致拍出來的照片,很尷尬,很不自然,那可以像圖2這樣,拍攝的時候,把自己的衣服,放到手臂上,兩個手搭在一起,兩條腿,不要直直地站在那裡,一前一後,並且有一條腿,適當彎曲,這樣的身姿,就會更加優...