Java中常用的設(shè)計模式之單例模式詳解
注意
1、單例類只能有一個實例。
2、單例類必須自己創(chuàng)建自己的唯一實例。
3、單例類必須給所有其他對象提供這一實例。
優(yōu)點
1.在內(nèi)存里只有一個實例,減少了內(nèi)存的開銷,尤其是頻繁的創(chuàng)建和銷毀實例(比如管理學(xué)院首頁頁面緩存)。
2.避免對資源的多重占用(比如寫文件操作)。
缺點
1.沒有接口,不能繼承,與單一職責(zé)原則沖突,一個類應(yīng)該只關(guān)心內(nèi)部邏輯,而不關(guān)心外面怎么樣來實例化。
使用場景
1.要求生產(chǎn)唯一序列號。
2.WEB 中的計數(shù)器,不用每次刷新都在數(shù)據(jù)庫里加一次,用單例先緩存起來。
3.創(chuàng)建的一個對象需要消耗的資源過多,比如 I/O 與數(shù)據(jù)庫的連接等。
一、實現(xiàn)方式
package com.asurplus.common.singleton.style1; import lombok.extern.slf4j.Slf4j; import java.util.Objects; @Slf4j public class ResUtils { private volatile static ResUtils instance = null; /** * 私有的構(gòu)造方法 */ private ResUtils() { } /** * 提供獲取實例的方法 * * @return */ public static ResUtils getInstance() { // 為空才創(chuàng)建 if (Objects.isNull(instance)) { // 避免并發(fā)操作時 synchronized (ResUtils.class) { // 為空才創(chuàng)建 if (Objects.isNull(instance)) { // 創(chuàng)建新對象 instance = new ResUtils(); log.info("創(chuàng)建了對象"); } } } return instance; } }
我們將其構(gòu)造方法私有化,從而外部無法創(chuàng)建實例,并且我們提供了獲取唯一實例的方法,這樣我們就能從外部得到該實例。
二、實現(xiàn)方式
package com.asurplus.common.singleton.style2; import lombok.extern.slf4j.Slf4j; @Slf4j public class ResUtils2 { /** * 靜態(tài)內(nèi)部類 */ private static class ResUtils2Holder { private static ResUtils2 instance = new ResUtils2(); } /** * 提供獲取實例的方法 * * @return */ public static ResUtils2 getInstance() { return ResUtils2Holder.instance; } }
我們使用靜態(tài)內(nèi)部類的方法創(chuàng)建實例,因為 JVM 只會加載一次的原理,所以最終只會創(chuàng)建一個實例,并且提供了獲取實例的方法,這樣我們就能從外部得到該實例。
三、測試
package com.asurplus.common.singleton; import com.asurplus.common.singleton.style1.ResUtils; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 單例模式 */ public class TestMain { public static void main(String[] args) { // 創(chuàng)建線程池 ExecutorService executorService = Executors.newFixedThreadPool(10); for (int i = 0; i < 100; i++) { executorService.execute(ResUtils::getInstance); } executorService.shutdown(); } }
輸出結(jié)果
可以看出,我們獲取了 100 次實例,只創(chuàng)建了一個實例,從而實現(xiàn)了我們的單例模式。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Java實現(xiàn)Promise.all()的示例代碼
這篇文章主要介紹了Java實現(xiàn)Promise.all()的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08SpringBoot3使用devtools實現(xiàn)代碼熱部署的詳細(xì)步驟
Spring Boot DevTools是一組用于提高開發(fā)人員生產(chǎn)力,并加速Spring Boot應(yīng)用程序開發(fā)的工具,它提供了一些功能,可以幫助開發(fā)人員更快速地構(gòu)建應(yīng)用程序,并減少常見的開發(fā)問題,本文給大家介紹了SpringBoot3使用devtools實現(xiàn)代碼熱部署的詳細(xì)步驟,需要的朋友可以參考下2024-01-01JAVA HashSet和TreeSet 保證存入元素不會重復(fù)的操作
這篇文章主要介紹了JAVA HashSet和TreeSet 保證存入元素不會重復(fù)的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09Springboot通過谷歌Kaptcha?組件生成圖形驗證碼功能
Kaptcha是谷歌開源的一款簡單實用的圖形驗證碼組件。我個人推薦它的最大原因是容易上手,采用約定大于配置的方式,快速契合到項目中,這篇文章主要介紹了Springboot通過谷歌Kaptcha組件生成圖形驗證碼的方法,需要的朋友可以參考下2023-05-05