Java單例模式利用HashMap實(shí)現(xiàn)緩存數(shù)據(jù)
本文實(shí)例為大家分享了Java單例模式利用HashMap實(shí)現(xiàn)緩存數(shù)據(jù)的具體代碼,供大家參考,具體內(nèi)容如下
一、單例模式是什么?
單例模式是一種對(duì)象創(chuàng)建模式,它用于產(chǎn)生一個(gè)對(duì)象的具體實(shí)例,它可以確保系統(tǒng)中一個(gè)類只產(chǎn)生一個(gè)實(shí)例。Java 里面實(shí)現(xiàn)的單例是一個(gè)虛擬機(jī)的范圍,因?yàn)檠b載類的功能是虛擬機(jī)的,所以一個(gè)虛擬機(jī)在通過自己的 ClassLoad 裝載實(shí)現(xiàn)單例類的時(shí)候就會(huì)創(chuàng)建一個(gè)類的實(shí)例。在 Java 語言中,這樣的行為能帶來兩大好處:
1.對(duì)于頻繁使用的對(duì)象,可以省略創(chuàng)建對(duì)象所花費(fèi)的時(shí)間,這對(duì)于那些重量級(jí)對(duì)象而言,是非常可觀的一筆系統(tǒng)開銷;
2.由于 new 操作的次數(shù)減少,因而對(duì)系統(tǒng)內(nèi)存的使用頻率也會(huì)降低,這將減輕 GC 壓力,縮短 GC 停頓時(shí)間。
因此對(duì)于系統(tǒng)的關(guān)鍵組件和被頻繁使用的對(duì)象,使用單例模式可以有效地改善系統(tǒng)的性能。單例模式的核心在于通過一個(gè)接口返回唯一的對(duì)象實(shí)例。首要的問題就是要把創(chuàng)建實(shí)例的權(quán)限收回來,讓類自身來負(fù)責(zé)自己類的實(shí)例的創(chuàng)建工作,然后由這個(gè)類來提供外部可以訪問這個(gè)類實(shí)例的方法
二、單例模式結(jié)合HashMap實(shí)現(xiàn)緩存
1.測(cè)試結(jié)果
2.代碼如下
JavaBean
public class People { ? ? private String name; ? ? private int age; ? ? public String getName() { ? ? ? ? return name; ? ? } ? ? public void setName(String name) { ? ? ? ? this.name = name; ? ? } ? ? public int getAge() { ? ? ? ? return age; ? ? } ? ? public void setAge(int age) { ? ? ? ? this.age = age; ? ? } ? ? @Override ? ? public String toString() { ? ? ? ? return "People{" + ? ? ? ? ? ? ? ? "name='" + name + '\'' + ? ? ? ? ? ? ? ? ", age=" + age + ? ? ? ? ? ? ? ? '}'; ? ? } }
緩存工具類
import java.util.HashMap; import java.util.Map; public class CacheSingletonUtil { ? ? private static volatile CacheSingletonUtil cacheSingletonUtil; ? ? private static Map<String,Object> cacheSingletonMap; ? ? public static final String PEOPLE_LIST_KEY = "peopleList"; ? ? private CacheSingletonUtil(){ ? ? ? ? cacheSingletonMap = new HashMap<String, Object>(); ? ? } ? ? /* ? ? ?* 單例模式有兩種類型 ? ? ?* 懶漢式:在真正需要使用對(duì)象時(shí)才去創(chuàng)建該單例類對(duì)象 ? ? ?* 餓漢式:在類加載時(shí)已經(jīng)創(chuàng)建好該單例對(duì)象,等待被程序使用 ? ? ?*/ ? ? // 懶漢式單例模式 ? ? public static CacheSingletonUtil getInstance(){ ? ? ? ? if (cacheSingletonUtil == null){// 線程A和線程B同時(shí)看到cacheSingletonUtil = null,如果不為null,則直接返回cacheSingletonUtil ? ? ? ? ? ? synchronized (CacheSingletonUtil.class) {// 線程A或線程B獲得該鎖進(jìn)行初始化 ? ? ? ? ? ? ? ? if (cacheSingletonUtil == null) {// 其中一個(gè)線程進(jìn)入該分支,另外一個(gè)線程則不會(huì)進(jìn)入該分支 ? ? ? ? ? ? ? ? ? ? cacheSingletonUtil = new CacheSingletonUtil(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return cacheSingletonUtil; ? ? } ? ? /** ? ? ?* 添加到內(nèi)存 ? ? ?*/ ? ? public void addCacheData(String key,Object obj){ ? ? ? ? cacheSingletonMap.put(key,obj); ? ? } ? ? /** ? ? ?* 從內(nèi)存中取出 ? ? ?*/ ? ? public Object getCacheData(String key){ ? ? ? ? return cacheSingletonMap.get(key); ? ? } ? ? /** ? ? ?* 從內(nèi)存中清除 ? ? ?*/ ? ? public void removeCacheData(String key){ ? ? ? ? cacheSingletonMap.remove(key); ? ? } }
測(cè)試類
import org.apache.commons.collections.CollectionUtils; import java.util.ArrayList; import java.util.List; public class CacheSingletonTest { ? ? public static void main(String[] args) { ? ? ? ? //測(cè)試查詢 ? ? ? ? testQuery(); ? ? } ? ? private static void testQuery () { ? ? ? ? System.out.println("第一次查詢開始"); ? ? ? ? query(); ? ? ? ? System.out.println("第一次查詢結(jié)束"); ? ? ? ? System.out.println("============="); ? ? ? ? System.out.println("第二次查詢開始"); ? ? ? ? query(); ? ? ? ? System.out.println("第二次查詢結(jié)束"); ? ? } ? ? /* ? ? ?* 查詢數(shù)據(jù) ? ? ?*/ ? ? private static List<People> query() { ? ? ? ? List<People> peopleList = null; ? ? ? ? List<People> cacheData = (List<People>) CacheSingletonUtil.getInstance().getCacheData(CacheSingletonUtil.PEOPLE_LIST_KEY); ? ? ? ? if (CollectionUtils.isNotEmpty(cacheData)) { ? ? ? ? ? ? System.out.println("從內(nèi)存中讀取"); ? ? ? ? ? ? peopleList = cacheData; ? ? ? ? } else { ? ? ? ? ? ? System.out.println("從數(shù)據(jù)庫中讀取"); ? ? ? ? ? ? peopleList = getData(); ? ? ? ? ? ? // 添加到內(nèi)存中 ? ? ? ? ? ? CacheSingletonUtil.getInstance().addCacheData(CacheSingletonUtil.PEOPLE_LIST_KEY, peopleList); ? ? ? ? } ? ? ? ? for (People people : peopleList) { ? ? ? ? ? ? System.out.println("name : " + people.getName() + " age : " + people.getAge()); ? ? ? ? } ? ? ? ? return peopleList; ? ? } ? ? /* ? ? ?* 刪除數(shù)據(jù) ? ? ?*/ ? ? private void deleteCache () { ? ? ? ? CacheSingletonUtil.getInstance().removeCacheData(CacheSingletonUtil.PEOPLE_LIST_KEY); ? ? } ? ? private static List<People> getData() { ? ? ? ? People p1 = new People(); ? ? ? ? p1.setName("Jack"); ? ? ? ? p1.setAge(25); ? ? ? ? People p2 = new People(); ? ? ? ? p2.setName("Brown"); ? ? ? ? p2.setAge(28); ? ? ? ? List<People> peopleList = new ArrayList<>(); ? ? ? ? peopleList.add(p1); ? ? ? ? peopleList.add(p2); ? ? ? ? return peopleList; ? ? } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Boot實(shí)現(xiàn)分布式鎖的自動(dòng)釋放的示例代碼
在實(shí)際開發(fā)中,我們可以使用 Redis、Zookeeper 等分布式系統(tǒng)來實(shí)現(xiàn)分布式鎖,本文將介紹如何使用 Spring Boot 來實(shí)現(xiàn)分布式鎖的自動(dòng)釋放,感興趣的朋友跟隨小編一起看看吧2023-06-06詳解如何給Sprintboot應(yīng)用添加插件機(jī)制
這篇文章主要為大家介紹了如何給 Sprintboot 應(yīng)用添加插件機(jī)制,文中有詳細(xì)的解決方案及示例代碼,具有一定的參考價(jià)值,需要的朋友可以參考下2023-08-08SpringBoot?SpringSecurity?JWT實(shí)現(xiàn)系統(tǒng)安全策略詳解
Spring?Security是Spring的一個(gè)核心項(xiàng)目,它是一個(gè)功能強(qiáng)大且高度可定制的認(rèn)證和訪問控制框架。它提供了認(rèn)證和授權(quán)功能以及抵御常見的攻擊,它已經(jīng)成為保護(hù)基于spring的應(yīng)用程序的事實(shí)標(biāo)準(zhǔn)2022-11-11JAVA對(duì)list集合進(jìn)行排序Collections.sort()
這篇文章主要介紹了JAVA對(duì)list集合進(jìn)行排序Collections.sort(),需要的朋友可以參考下2017-01-01mybatis-plus動(dòng)態(tài)表名的實(shí)現(xiàn)示例
這篇文章主要介紹了mybatis-plus動(dòng)態(tài)表名的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Java中鎖的實(shí)現(xiàn)和內(nèi)存語義淺析
這篇文章主要給大家介紹了關(guān)于Java中鎖的實(shí)現(xiàn)和內(nèi)存語義的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11spring boot springMVC擴(kuò)展配置實(shí)現(xiàn)解析
這篇文章主要介紹了spring boot springMVC擴(kuò)展配置實(shí)現(xiàn)解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08