什么是單例讹剔?
單例模式(Singleton Pattern)是 Java 中最簡(jiǎn)單的設(shè)計(jì)模式之一。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式详民,它提供了一種創(chuàng)建對(duì)象的最佳方式延欠。這種模式涉及到一個(gè)單一的類,該類負(fù)責(zé)創(chuàng)建自己的對(duì)象沈跨,同時(shí)確保只有單個(gè)對(duì)象被創(chuàng)建由捎。這個(gè)類提供了一種訪問(wèn)其唯一的對(duì)象的方式,可以直接訪問(wèn)饿凛,不需要實(shí)例化該類的對(duì)象狞玛。
單例介紹:
意圖:保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問(wèn)它的全局訪問(wèn)點(diǎn)涧窒。
主要解決:一個(gè)全局使用的類頻繁地創(chuàng)建與銷毀心肪。
何時(shí)使用:當(dāng)您想控制實(shí)例數(shù)目,節(jié)省系統(tǒng)資源的時(shí)候杀狡。
如何解決:判斷系統(tǒng)是否已經(jīng)有這個(gè)單例蒙畴,如果有則返回贰镣,如果沒(méi)有則創(chuàng)建呜象。
關(guān)鍵代碼:構(gòu)造函數(shù)是私有的膳凝。
優(yōu)點(diǎn):
1、在內(nèi)存里只有一個(gè)實(shí)例恭陡,減少了內(nèi)存的開(kāi)銷蹬音,尤其是頻繁的創(chuàng)建和銷毀實(shí)例。
2休玩、避免對(duì)資源的多重占用(比如寫文件操作)著淆。
缺點(diǎn):
缺點(diǎn):沒(méi)有接口,不能繼承拴疤,與單一職責(zé)原則沖突永部,一個(gè)類應(yīng)該只關(guān)心內(nèi)部邏輯,而不關(guān)心外面怎么樣來(lái)實(shí)例化呐矾。
代碼實(shí)現(xiàn)(傳統(tǒng)實(shí)現(xiàn)):
/**
* 單例一:餓漢式
* @author 愛(ài)折騰的程序猿
* @version 1.0
* @date 2019/12/27 16:57
*/
public class Singleton_01 {
private static Singleton_01 instance = new Singleton_01();
private Singleton_01() {
}
public static Singleton_01 getInstance() {
return instance;
}
}
什么是序列化苔埋?
序列化 (Serialization)是將對(duì)象的狀態(tài)信息轉(zhuǎn)換為可以存儲(chǔ)或傳輸?shù)男问降倪^(guò)程。在序列化期間蜒犯,對(duì)象將其當(dāng)前狀態(tài)寫入到臨時(shí)或持久性存儲(chǔ)區(qū)组橄。以后,可以通過(guò)從存儲(chǔ)區(qū)中讀取或反序列化對(duì)象的狀態(tài)罚随,重新創(chuàng)建該對(duì)象玉工。
什么是序列化不安全?
序列化不安全指的是淘菩,同一個(gè)序列化對(duì)象遵班,反序列化生成的對(duì)象不一致,這樣單例就失去了意義潮改,同時(shí)也成為了序列化攻擊的漏洞费奸。
如何解決餓漢式單例序列化不安全?
//解決序列化不安全
private Object readResolve(){
return instance;
}
解決序列化不安全(餓漢式升級(jí)版)
import java.io.Serializable;
/**
* 單例一:餓漢式
* @author 愛(ài)折騰的程序猿
* @version 1.0
* @date 2019/12/27 16:57
*/
public class Singleton_01 implements Serializable {
private static Singleton_01 instance = new Singleton_01();
private Singleton_01() {
}
public static Singleton_01 getInstance() {
return instance;
}
//解決序列化不安全
private Object readResolve(){
return instance;
}
}
餓漢式單例總結(jié)
一句話總結(jié)單例:
單例類在整個(gè)程序中只有一個(gè)實(shí)例进陡,這個(gè)類負(fù)責(zé)創(chuàng)建自己的對(duì)象愿阐,并確保只有一個(gè)對(duì)象被創(chuàng)建
代碼實(shí)現(xiàn)三個(gè)要點(diǎn):
a) 私有構(gòu)造器
b) 持有該類的屬性
c) 對(duì)外提供獲取實(shí)例的靜態(tài)方法
傳統(tǒng)餓漢式:
線程安全、反射不安全趾疚、反序列化不安全
升級(jí)后的餓漢式:
線程安全缨历、反射不安全、反序列化安全
如何判斷反射是否安全
反射安全:通過(guò)反射創(chuàng)建的對(duì)象是同一個(gè)對(duì)象
反射不安全:通過(guò)反射創(chuàng)建的對(duì)象是不同對(duì)象
如何判斷反序列化是否安全
反序列化安全:通過(guò)反序列化創(chuàng)建的對(duì)象是同一個(gè)對(duì)象
反序列化不安全:通過(guò)反序列化創(chuàng)建的對(duì)象是不同對(duì)象
下節(jié)預(yù)告:下節(jié)講述登記式單例的具體實(shí)現(xiàn)