java單例五種實(shí)現(xiàn)模式解析
餓漢式(線程安全,調(diào)用效率高,但是不能延時(shí)加載)
一上來就把單例對(duì)象創(chuàng)建出來了,要用的時(shí)候直接返回即可,這種可以說是單例模式中最簡(jiǎn)單的一種實(shí)現(xiàn)方式。但是問題也比較明顯。單例在還沒有使用到的時(shí)候,初始化就已經(jīng)完成了。也就是說,如果程序從頭到位都沒用使用這個(gè)單例的話,單例的對(duì)象還是會(huì)創(chuàng)建。這就造成了不必要的資源浪費(fèi)。所以不推薦這種實(shí)現(xiàn)方式。
public class ImageLoader{
private static ImageLoader instance = new ImageLoader;
private ImageLoader(){}
public static ImageLoader getInstance(){
return instance;
}
}
懶漢式(線程安全,調(diào)用效率不高,但是能延時(shí)加載)
public class SingletonDemo2 {
//類初始化時(shí),不初始化這個(gè)對(duì)象(延時(shí)加載,真正用的時(shí)候再創(chuàng)建)
private static SingletonDemo2 instance;
//構(gòu)造器私有化
private SingletonDemo2(){}
//方法同步,調(diào)用效率低
public static synchronized SingletonDemo2 getInstance(){
if(instance==null){
instance=new SingletonDemo2();
}
return instance;
}
}
靜態(tài)內(nèi)部類實(shí)現(xiàn)模式(線程安全,調(diào)用效率高,可以延時(shí)加載)
可以看到使用這種方式我們沒有顯式的進(jìn)行任何同步操作,那他是如何保證線程安全呢?和餓漢模式一樣,是靠JVM保證類的靜態(tài)成員只能被加載一次的特點(diǎn),這樣就從JVM層面保證了只會(huì)有一個(gè)實(shí)例對(duì)象。
那么問題來了,這種方式和餓漢模式又有什么區(qū)別呢?不也是立即加載么?實(shí)則不然,加載一個(gè)類時(shí),其內(nèi)部類不會(huì)同時(shí)被加載。一個(gè)類被加載,當(dāng)且僅當(dāng)其某個(gè)靜態(tài)成員(靜態(tài)域、構(gòu)造器、靜態(tài)方法等)被調(diào)用時(shí)發(fā)生。
但是在遇到序列化對(duì)象時(shí),默認(rèn)的方式運(yùn)行得到的結(jié)果就是多例的。這種情況不多做說明了,使用時(shí)請(qǐng)注意。
public class SingletonDemo3 {
private static class SingletonClassInstance{
private static final SingletonDemo3 instance=new SingletonDemo3();
}
private SingletonDemo3(){}
public static SingletonDemo3 getInstance(){
return SingletonClassInstance.instance;
}
}
枚舉類(線程安全,調(diào)用效率高,不能延時(shí)加載,可以天然的防止反射和反序列化調(diào)用)
public enum SingletonDemo4 {
//枚舉元素本身就是單例
INSTANCE;
//添加自己需要的操作
public void singletonOperation(){
}
}
Double CheckLock實(shí)現(xiàn)單例:DCL也就是雙重鎖判斷機(jī)制(由于JVM底層模型原因,偶爾會(huì)出問題,不建議使用)
選用
單例對(duì)象 占用資源少,不需要延時(shí)加載,枚舉 好于 餓漢
單例對(duì)象 占用資源多,需要延時(shí)加載,靜態(tài)內(nèi)部類 好于 懶漢式
注意線程安全問題
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java使用BigDecimal進(jìn)行運(yùn)算封裝的實(shí)際案例
今天小編就為大家分享一篇關(guān)于Java使用BigDecimal進(jìn)行運(yùn)算封裝的實(shí)際案例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12
Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之校園一卡通系統(tǒng)的實(shí)現(xiàn)
這是一個(gè)使用了java+Springboot+Maven+mybatis+Vue+mysql+wd開發(fā)的校園一卡通系統(tǒng),是一個(gè)畢業(yè)設(shè)計(jì)的實(shí)戰(zhàn)練習(xí),具有校園一卡通系統(tǒng)該有的所有功能,感興趣的朋友快來看看吧2022-01-01
Spring Boot 中整合 MyBatis-Plus詳細(xì)步驟(最新推薦)
本文詳細(xì)介紹了如何在SpringBoot項(xiàng)目中整合MyBatis-Plus,包括整合步驟、基本CRUD操作、分頁(yè)查詢、批量操作、自定義SQL操作等,通過這些步驟,開發(fā)者可以快速實(shí)現(xiàn)數(shù)據(jù)庫(kù)操作,提高開發(fā)效率,感興趣的朋友一起看看吧2025-01-01
Mybatis plus關(guān)閉駝峰命名的四種方法(防止出現(xiàn)查詢?yōu)镹ull)
這篇文章主要介紹了Mybatis plus關(guān)閉駝峰命名的四種方法(防止出現(xiàn)查詢?yōu)镹ull),數(shù)據(jù)庫(kù)的字段命名方式為使用下劃線連接,對(duì)應(yīng)的實(shí)體類應(yīng)該是駝峰命名方式,而我使用的是和數(shù)據(jù)庫(kù)同樣的命名方式,需要的朋友可以參考下2022-01-01
java web學(xué)習(xí)_淺談request對(duì)象中g(shù)et和post的差異
下面小編就為大家?guī)硪黄猨ava web學(xué)習(xí)_淺談request對(duì)象中g(shù)et和post的差異。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05
Spring 應(yīng)用中集成 Apache Shiro的方法
這篇文章主要介紹了Spring 應(yīng)用中集成 Apache Shiro的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05

