單例模式
單例模式(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ì)象。
1备徐、懶漢式萄传,線程不安全
是否 Lazy 初始化:是
是否多線程安全:否
實(shí)現(xiàn)難度:易
描述:這種方式是最基本的實(shí)現(xiàn)方式,這種實(shí)現(xiàn)最大的問(wèn)題就是不支持多線程。因?yàn)闆](méi)有加鎖 synchronized秀菱,所以嚴(yán)格意義上它并不算單例模式振诬。這種方式 lazy loading 很明顯,不要求線程安全衍菱,在多線程不能正常工作赶么。
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
2、懶漢式脊串,線程安全
是否 Lazy 初始化:是
是否多線程安全:是
實(shí)現(xiàn)難度:易
描述:這種方式具備很好的 lazy loading辫呻,能夠在多線程中很好的工作,但是琼锋,效率很低放闺,99% 情況下不需要同步。
優(yōu)點(diǎn):第一次調(diào)用才初始化缕坎,避免內(nèi)存浪費(fèi)怖侦。
缺點(diǎn):必須加鎖 synchronized 才能保證單例,但加鎖會(huì)影響效率谜叹。getInstance() 的性能對(duì)應(yīng)用程序不是很關(guān)鍵(該方法使用不太頻繁)匾寝。
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
3、餓漢式
是否 Lazy 初始化:否
是否多線程安全:是
實(shí)現(xiàn)難度:易
描述:這種方式比較常用荷腊,但容易產(chǎn)生垃圾對(duì)象艳悔。
優(yōu)點(diǎn):沒(méi)有加鎖,執(zhí)行效率會(huì)提高停局。
缺點(diǎn):類加載時(shí)就初始化很钓,浪費(fèi)內(nèi)存。
它基于 classloader 機(jī)制避免了多線程的同步問(wèn)題董栽,不過(guò)码倦,instance 在類裝載時(shí)就實(shí)例化,雖然導(dǎo)致類裝載的原因有很多種锭碳,在單例模式中大多數(shù)都是調(diào)用 getInstance 方法袁稽, 但是也不能確定有其他的方式(或者其他的靜態(tài)方法)導(dǎo)致類裝載,這時(shí)候初始化 instance 顯然沒(méi)有達(dá)到 lazy loading 的效果擒抛。
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}