java單例模式學(xué)習(xí)示例
單例模式有一下特點(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)中,線(xiàn)程池、緩存、日志對(duì)象、對(duì)話(huà)框、打印機(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)用??傊?,選擇單例模式就是為了避免不一致?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()方法訪(fǎng)問(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)有考慮線(xiàn)程安全問(wèn)題。所謂線(xiàn)程安全是指:如果你的代碼所在的進(jìn)程中有多個(gè)線(xiàn)程在同時(shí)運(yùn)行,而這些線(xiàn)程可能會(huì)同時(shí)運(yùn)行這段代碼。如果每次運(yùn)行結(jié)果和單線(xiàn)程運(yùn)行的結(jié)果是一樣的,而且其他的變量的值也和預(yù)期的是一樣的,就是線(xiàn)程安全的?;蛘哒f(shuō):一個(gè)類(lèi)或者程序所提供的接口對(duì)于線(xiàn)程來(lái)說(shuō)是原子操作或者多個(gè)線(xiàn)程之間的切換不會(huì)導(dǎo)致該接口的執(zhí)行結(jié)果存在二義性,也就是說(shuō)我們不用考慮同步的問(wèn)題。顯然以上實(shí)現(xiàn)并不滿(mǎn)足線(xiàn)程安全的要求,在并發(fā)環(huán)境下很可能出現(xiàn)多個(gè)Singleton實(shí)例。
//餓漢式單例類(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)工廠(chǎng)方法
public static Singleton1 getInstance() {
return single;
}
}
//懶漢式單例類(lèi).在第一次調(diào)用的時(shí)候?qū)嵗?BR>public class Singleton2 {
//私有的默認(rèn)構(gòu)造子
private Singleton2() {}
//注意,這里沒(méi)有final
private static Singleton2 single=null;
//靜態(tài)工廠(chǎng)方法
public synchronized static Singleton2 getInstance() {
if (single == null) {
single = new Singleton2();
}
return single;
}
}
相關(guān)文章
Java實(shí)現(xiàn)curl調(diào)用帶參數(shù)接口方法
本文主要介紹了Java實(shí)現(xiàn)curl調(diào)用帶參數(shù)接口方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-04-04
java中springMVC獲取請(qǐng)求參數(shù)的方法
這篇文章主要介紹了java中springMVC獲取請(qǐng)求參數(shù)的方法,springmvc是spring框架的一個(gè)模塊,springmvc和spring無(wú)需通過(guò)中間整合層進(jìn)行整合,需要的朋友可以參考下2023-05-05
10個(gè)Java解決內(nèi)存溢出OOM的方法詳解
在Java開(kāi)發(fā)過(guò)程中,有效的內(nèi)存管理是保證應(yīng)用程序穩(wěn)定性和性能的關(guān)鍵,不正確的內(nèi)存使用可能導(dǎo)致內(nèi)存泄露甚至是致命的OutOfMemoryError(OOM),下面我們就來(lái)學(xué)習(xí)一下有哪些解決辦法吧2024-01-01
SpringBoot中發(fā)送QQ郵件功能的實(shí)現(xiàn)代碼
這篇文章主要介紹了SpringBoot中發(fā)送QQ郵件功能的實(shí)現(xiàn)代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2018-02-02
Idea運(yùn)行單個(gè)main方法,不編譯整個(gè)工程的問(wèn)題
這篇文章主要介紹了Idea運(yùn)行單個(gè)main方法,不編譯整個(gè)工程的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
Java框架篇:Spring+SpringMVC+hibernate整合開(kāi)發(fā)
本篇文章將會(huì)對(duì)Spring+SpringMVC+hibernate的整合開(kāi)發(fā)進(jìn)行介紹。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-02-02
解析Orika的MapperFacade 屬性賦值的使用問(wèn)題
在我們實(shí)際開(kāi)發(fā)中,常常會(huì)有對(duì)象與對(duì)象之間的轉(zhuǎn)化,或者把一個(gè)對(duì)象的數(shù)據(jù)轉(zhuǎn)化到另一個(gè)數(shù)據(jù)之中,如果我們手動(dòng)的一個(gè)一個(gè)的set就會(huì)比較麻煩,代碼段看起來(lái)也會(huì)比較長(zhǎng)。而Orika的MapperFacade就是解決這個(gè)問(wèn)題的,實(shí)現(xiàn)對(duì)象屬性的復(fù)制2021-12-12

