詳解Java中的八種單例創(chuàng)建方式
定義
單例設(shè)計(jì)模式,就是采取一定的方法保證在整個(gè)的軟件系統(tǒng)中,對(duì)某個(gè)類只能存在一個(gè)對(duì)象實(shí)例,并且該類只提供一個(gè)取得其對(duì)象實(shí)例的方法(靜態(tài)方法)
使用場景
- 對(duì)于一些需要頻繁創(chuàng)建銷毀的對(duì)象
- 重量級(jí)的對(duì)象
- 經(jīng)常使用到的對(duì)象
- 工具類對(duì)象
- 數(shù)據(jù)源
- session
單例模式八種方式
餓漢式(靜態(tài)常量)
代碼
/** * 餓漢式(靜態(tài)常量) * 優(yōu)勢(shì):簡單,避免多線程的同步問題 * 劣勢(shì):無懶加載,內(nèi)存浪費(fèi) * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ public class Singleton1 { // 私有化構(gòu)造方法 private Singleton1(){} // 靜態(tài)常量 private static final Singleton1 singleton1 = new Singleton1(); // 對(duì)外提供公共方法 public static Singleton1 getSingleton1(){ return singleton1; } }
分析
- 優(yōu)勢(shì):簡單,避免多線程的同步問題
- 劣勢(shì):無懶加載,內(nèi)存浪費(fèi)
餓漢式(靜態(tài)代碼塊)
代碼
/** * 餓漢式(靜態(tài)代碼塊) * 優(yōu)勢(shì):簡單,避免多線程的同步問題 * 劣勢(shì):無懶加載,內(nèi)存浪費(fèi) * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ public class Singleton2 { // 私有化構(gòu)造方法 private Singleton2(){} private static final Singleton2 singleton2; // 靜態(tài)代碼塊 static { singleton2 = new Singleton2(); } // 對(duì)外提供公共方法 public static Singleton2 getSingleton2(){ return singleton2; } }
分析
- 優(yōu)勢(shì):簡單,避免多線程的同步問題
- 劣勢(shì):無懶加載,內(nèi)存浪費(fèi)
懶漢式(線程不安全)
代碼
/** * 懶漢式(線程不安全) * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ public class Singleton3 { // 私有化構(gòu)造方法 private Singleton3(){} // 內(nèi)部屬性 private static Singleton3 singleton3; // 對(duì)外提供公共方法 public static Singleton3 getSingletons(){ if(singleton3 == null){ singleton3 = new Singleton3(); } return singleton3; } }
分析
- 優(yōu)勢(shì):起到了懶加載的效果 不會(huì)造成內(nèi)存浪費(fèi)
- 劣勢(shì):線程不安全 不推薦這種方式的
懶漢式(同步方法)
代碼
/** * 懶漢式(同步方法) * 優(yōu)勢(shì):解決了線程同步問題 * 劣勢(shì):使用synchronized同步關(guān)鍵字,性能太低 * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ public class Singleton4 { // 私有化構(gòu)造方法 private Singleton4(){} // 內(nèi)部屬性 private static Singleton4 singleton4; // 對(duì)外提供公共方法 public static synchronized Singleton4 getSingleton4(){ if(singleton4 == null){ singleton4 = new Singleton4(); } return singleton4; } }
分析
- 優(yōu)勢(shì):解決了線程安全問題,
- 劣勢(shì):效率太低
懶漢式(同步代碼塊)
代碼
/** * 懶漢式(同步代碼塊) * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ public class Singleton5 { // 私有化構(gòu)造方法 private Singleton5(){} // 內(nèi)部屬性 private static Singleton5 singleton5; // 對(duì)外提供公共方法 public static Singleton5 getSingleton5(){ if (singleton5 == null){ synchronized (Singleton5.class){ singleton5 = new Singleton5(); } } return singleton5; } }
分析
- 優(yōu)勢(shì):起到了懶加載的效果 不會(huì)造成內(nèi)存浪費(fèi)
- 劣勢(shì):線程不安全 不推薦這種方式的
雙重檢查鎖方式
代碼
/** * 雙重檢查鎖機(jī)制 * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ public class Singleton6 { // 私有化構(gòu)造方法 private Singleton6(){} // 內(nèi)部屬性 private volatile static Singleton6 singleton6; // 對(duì)外提供公共方法 public static Singleton6 getSingleton6(){ if (singleton6 == null){ synchronized (Singleton6.class){ if(singleton6 == null){ singleton6 = new Singleton6(); } } } return singleton6; } }
分析
- 實(shí)現(xiàn)了懶加載,效率很高,解決了線程安全
靜態(tài)內(nèi)部類方式
代碼
/** * 靜態(tài)內(nèi)部類 * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ public class Singleton7 { // 私有化構(gòu)造方法 private Singleton7(){} // 內(nèi)部類 private static class SingleInstance{ public static final Singleton7 singleton7 = new Singleton7(); } // 對(duì)外提供公共方法 public static Singleton7 getSingleton7(){ return SingleInstance.singleton7; } }
分析
- 不會(huì)出現(xiàn)線程安全問題 JVM來幫我們保證了線程的安全性
- 利用靜態(tài)內(nèi)部類的特點(diǎn),效率也很高,
- 實(shí)際開發(fā)中推薦使用的
枚舉方式
代碼
定義單例對(duì)象
/** * @desc: * @author:liyajie * @createTime:2022/2/11 10:25 * @version:1.0 */ public class Singleton { public void hello(){ System.out.println("hello"); } }
定義枚舉實(shí)例化單例對(duì)象
/** * 枚舉方式 * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ enum Singleton8 { // 相當(dāng)于public static final Singleton8 INSTANCE; // 保證了枚舉實(shí)例只能被實(shí)例化一次 INSTANCE; // 定義單例變量 private Singleton singleton; // 枚舉構(gòu)造方法,該構(gòu)造方法是private,執(zhí)行構(gòu)造方法的時(shí)候,同時(shí)創(chuàng)建我們的單例對(duì)象 Singleton8() { singleton = new Singleton(); } // 對(duì)外提供公共方法 public Singleton getSingleton() { return singleton; } }
使用方法Singleton8.INSTANCE.getSingleton()即可獲取我們的單例對(duì)象了
分析
- 簡單,避免了線程安全問題
- 實(shí)際開發(fā)中推薦使用的
總結(jié)
1.單例模式保證了系統(tǒng)內(nèi)存中該類只存在一個(gè)對(duì)象,節(jié)省了系統(tǒng)資源,對(duì)于一些需要頻繁創(chuàng)建銷毀的對(duì)象, 使用單例模式可以提高系統(tǒng)性能
2.當(dāng)想實(shí)例化一個(gè)單例類的時(shí)候,必須要記住使用相應(yīng)的獲取對(duì)象的方法,而不是使用new
3.單例模式推薦使用的方法有內(nèi)部靜態(tài)類方式和枚舉方式
到此這篇關(guān)于詳解Java中的八種單例創(chuàng)建方式的文章就介紹到這了,更多相關(guān)Java單例創(chuàng)建方式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java的內(nèi)存區(qū)域與內(nèi)存溢出異常你了解嗎
這篇文章主要為大家詳細(xì)介紹了Java的內(nèi)存區(qū)域與內(nèi)存溢出異常,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03Spring Boot中使用Activiti的方法教程(二)
工作流(Workflow),就是“業(yè)務(wù)過程的部分或整體在計(jì)算機(jī)應(yīng)用環(huán)境下的自動(dòng)化”,下面這篇文章主要給大家介紹了關(guān)于Spring Boot中使用Activiti的相關(guān)資料,需要的朋友可以參考下2018-08-08IDEA 2019.2.2配置Maven3.6.2打開Maven項(xiàng)目出現(xiàn) Unable to import Maven
這篇文章主要介紹了IDEA 2019.2.2配置Maven3.6.2打開Maven項(xiàng)目出現(xiàn) Unable to import Maven project的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12SpringBoot設(shè)置默認(rèn)主頁的方法步驟
這篇文章主要介紹了SpringBoot設(shè)置默認(rèn)主頁的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12