java內存緩存

?我們在項目中會經常使Redis和Memcache,但是簡單項目就沒必要使用專門的緩存框架來增加系統的復雜性。用Java代碼邏輯就能實現內存級別的緩存。

1.定時任務線程池

使用ScheduledExecutorService結合ConcurrentHashMap,如果你使用的是ConcurrentHashMap,你可以結合使用ScheduledExecutorService來定期檢查并清理過期的條目。

public class ExpiringMap<K, V> {private final ConcurrentHashMap<K, ExpiringValue> map = new ConcurrentHashMap<>();private final long expirationTime; // 毫秒private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);public ExpiringMap(long expirationTime) {this.expirationTime = expirationTime;// 安排一個任務定期檢查并清理過期條目scheduler.scheduleAtFixedRate(this::cleanUp, expirationTime, expirationTime, TimeUnit.MILLISECONDS);}public void put(K key, V value) {map.put(key, new ExpiringValue(value, System.currentTimeMillis() + expirationTime));}private void cleanUp() {long currentTime = System.currentTimeMillis();map.entrySet().removeIf(entry -> entry.getValue().expirationTime < currentTime);}static class ExpiringValue {final V value;final long expirationTime;ExpiringValue(V value, long expirationTime) {this.value = value;this.expirationTime = expirationTime;}}
}

2.?java.time.Instant

和方式一類似,使用java.time.Instant來手動管理過期時間,并結合一個后臺線程來定期清理。

public class ExpiringMapWithManualCleanup<K, V> {private final Map<K, Entry<V>> map = new ConcurrentHashMap<>(); private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);private final long expirationTime; // 毫秒public ExpiringMapWithManualCleanup(long expirationTime) {this.expirationTime = expirationTime;scheduler.scheduleAtFixedRate(this::cleanUp, expirationTime, expirationTime, TimeUnit.MILLISECONDS);}public void put(K key, V value) {map.put(key, new Entry<>(value, Instant.now().plusMillis(expirationTime)));}private void cleanUp() {Instant now = Instant.now();map.entrySet().removeIf(entry -> entry.getValue().expirationTime.isBefore(now));}static class Entry<V> {final V value;final Instant expirationTime;Entry(V value, Instant expirationTime) {this.value = value;this.expirationTime = expirationTime;}}
}

3.?使用第三方庫

?3.1 ExpiringMap使用

引入依賴

        <dependency><groupId>net.jodah</groupId><artifactId>expiringmap</artifactId><version>0.5.10</version></dependency>
    /*** ① maxSize:Map存儲的最大值,類似隊列,容量固定,當操作map容量超出限制時,最開始的元素就會依次過期,只保留最新的;* ② expiration:過期時間;* ③ expirationListener:過期監聽,當條目過期時,將同步調用過期偵聽器,并且在偵聽器完成之前,*  將阻止對映射的寫入操作。還可以在單獨的線程池中配置和調用異步過期偵聽器,而不會阻塞映射操作;* ④ expirationPolicy:過期策略,包括 ExpirationPolicy.ACCESSED 和 ExpirationPolicy.CREATED 兩種;*      1)ExpirationPolicy.ACCESSED :每進行一次訪問,過期時間就會自動清零,重新計算;*      2)ExpirationPolicy.CREATED:在過期時間內重新 put 值的話,過期時間會清理,重新計算;* ⑤ variableExpiration:可變過期,條目可以具有單獨可變的到期時間和策略:*/public static  ExpiringMap<String, String> map = ExpiringMap.builder().maxSize(1000).expiration(2, TimeUnit.HOURS).variableExpiration().expirationPolicy(ExpirationPolicy.ACCESSED).expirationListener((key, value) -> {System.out.println("SseEmitter已過期,key:"+ key);}).build();

使用

//為單個條目指定到期策略:map.put("1", "張三", ExpirationPolicy.CREATED);map.put("2", "李四", ExpirationPolicy.ACCESSED);//variableExpiration 可變過期 條目可以具有單獨可變的到期時間和策略:map.put("3", "王五", ExpirationPolicy.ACCESSED, 5, TimeUnit.MINUTES);//過期時間和策略也可以即時更改:map.setExpiration("1", 5, TimeUnit.MINUTES);map.setExpirationPolicy("1", ExpirationPolicy.ACCESSED);//動態添加和刪除過期偵聽器:ExpirationListener<String, String> connectionCloser = (key, value) -> System.out.println(key+":"+value);//添加偵聽器map.addExpirationListener(connectionCloser);//移除偵聽器map.removeExpirationListener(connectionCloser);//設置懶加載
//        Map<String, String> stringMap = ExpiringMap.builder()
//                .expiration(10, TimeUnit.MINUTES)
//                .entryLoader(address -> address)
//                .build();
//        // 通過 EntryLoader 將值加載到map中
//        String value = stringMap.get("1");
//        System.out.println("value值:"+value);//獲取條目的到期時間:單位:毫秒long expiration = map.getExpectedExpiration("1");System.out.println("距離過期時間還有:"+expiration+"毫秒");//重置條目的內部到期計時器:map.resetExpiration("1");//查看設置的過期時間map.getExpiration("1");System.out.println("設置的過期時間:"+map.getExpiration("1"));

3.2 Google的Guava的LoadingCache

引入依賴

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>24.1-jre</version>
</dependency>
maximumSize:緩存的k-v最大數據,當總緩存的數據量達到這個值時,就會淘汰它認為不太用的一份數據,會使用LRU策略進行回收;
expireAfterAccess:緩存項在給定時間內沒有被讀/寫訪問,則回收,這個策略主要是為了淘汰長時間不被訪問的數據;
expireAfterWrite:緩存項在給定時間內沒有被寫訪問(創建或覆蓋),則回收, 防止舊數據被緩存過久;
refreshAfterWrite:緩存項在給定時間內沒有被寫訪問(創建或覆蓋),則刷新;
recordStats:開啟Cache的狀態統計(默認是開啟的);
removalListener:移除監聽器,緩存項被移除時會觸發
build:處理緩存鍵對應的緩存值不存在時的處理邏輯public static LoadingCache<Long, String> userCache= CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(60, TimeUnit.SECONDS).expireAfterWrite(60, TimeUnit.SECONDS).refreshAfterWrite(10, TimeUnit.SECONDS).removalListener(new RemovalListener() {@Overridepublic void onRemoval(RemovalNotification rn) {log.error(rn.getKey() + "remove");}}).build(new CacheLoader<Long, String>() {@Overridepublic String load(Long aLong) throws Exception {return "";}});

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/93229.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/93229.shtml
英文地址,請注明出處:http://en.pswp.cn/web/93229.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

智能工廠生產監控大屏-vue純前端靜態頁面練習

學習前端還是非常有意思的&#xff0c;因為前端真的是可見即所得&#xff0c;可以做出來非常好看漂亮的頁面&#xff0c;最近我就在使用前端技術 做一些大屏報表&#xff0c;在制作這些大屏報表過程中&#xff0c;又熟練的練習了自己的學到的相關的前端技術&#xff0c;接下來把…

HTTP 協議詳細介紹

目錄一、HTTP 的基本概念與歷史演進1. 核心定義2. 歷史版本演進二、HTTP 的核心工作原理1. 請求-響應模型2. 基于 TCP 的傳輸&#xff08;HTTP/1.1、HTTP/2&#xff09;三、HTTP 請求結構1. 請求行2. 請求頭3. 請求體四、HTTP 響應結構1. 狀態行2. 響應頭3. 響應體五、HTTP 與 …

正則化:從過擬合到泛化的「平衡藝術」

在機器學習領域&#xff0c;有一個幾乎所有從業者都會遇到的「噩夢」&#xff1a;模型在訓練集上表現完美&#xff08;損失趨近于0&#xff09;&#xff0c;但在測試集上卻大幅「翻車」。這種現象被稱為「過擬合」&#xff08;Overfitting&#xff09;&#xff0c;它像一把雙刃…

[Python 基礎課程]根據描述定義一個 Person 類

人都屬于人類這個物種&#xff0c;每一個人都會有姓名和年齡&#xff0c;人都可以介紹自己&#xff0c;隨著時間的流逝&#xff0c;人都會增加年齡&#xff0c;每一個人都能獲取到自己的物種信息。 我們的抽象過程&#xff1a; 所有的 Person 對象都應該有一個共同的屬性來表示…

熱門手機機型重啟速度對比

以下是2023-2024年市場主流熱門手機機型的重啟速度對比分析&#xff0c;基于公開測試數據和用戶反饋整理&#xff08;數據會因系統版本和測試環境不同存在波動&#xff09;&#xff1a;旗艦機型重啟速度排名&#xff08;冷啟動&#xff09;排名機型平均重啟時間關鍵配置優化技術…

第454題.四數相加II

第454題.四數相加II 力扣題目鏈接(opens new window) 給定四個包含整數的數組列表 A , B , C , D ,計算有多少個元組 (i, j, k, l) &#xff0c;使得 A[i] B[j] C[k] D[l] 0。 為了使問題簡單化&#xff0c;所有的 A, B, C, D 具有相同的長度 N&#xff0c;且 0 ≤ N ≤…

力扣top100(day04-05)--堆

本文為力扣TOP100刷題筆記 筆者根據數據結構理論加上最近刷題整理了一套 數據結構理論加常用方法以下為該文章&#xff1a; 力扣外傳之數據結構&#xff08;一篇文章搞定數據結構&#xff09; 215. 數組中的第K個最大元素 class Solution {// 快速選擇遞歸函數int quickselect(…

CCS雙軸相位偏移光源 讓淺凹痕無處遁形

在工業檢測中&#xff0c;淺凹痕表面檢測對精度和可靠性要求極高&#xff0c;工業光源在此過程中扮演著關鍵角色&#xff0c;工業光源通過精準的光學設計&#xff08;角度、波長、強度&#xff09;將肉眼不可見的淺凹痕轉化為可量化的光學信號&#xff0c;是實現高精度自動化檢…

專題三_二分_x 的平方根

一&#xff1a;題目解釋&#xff1a;返回x的算數平方根&#xff0c;如果是小數&#xff0c;則舍去小數部分&#xff0c;返回整數即可&#xff01;二&#xff1a;算法①&#xff1a;暴力從1開始求平方&#xff0c;最后要么直接找到一個值的平方為x&#xff0c;要么發現x在兩個相…

Python 操作 Redis 的客戶端庫 redis-py

Python 操作 Redis 的客戶端庫 redis-py1. Installation2. Connect and test3. Connection Pools4. Redis Commands4.1. set(name, value, exNone, pxNone, nxFalse, xxFalse, keepttlFalse, getFalse, exatNone, pxatNone)4.1.1. setnx(name, value)4.1.2. setex(name, time, …

社區物業HCommunity本地部署手冊

HC小區管理系統安裝手動版 更多文章參考&#xff1a; http://www.homecommunity.cn/pages/hc/hcH5_cn.html 1.0 說明 很多開發不太喜歡用梓豪安裝&#xff0c;希望通過手工自己安裝&#xff0c;這個就需要開發人員 有一定的安裝軟件能力&#xff0c;比如能夠自行安裝mysql能…

單例模式-使用局部變量懶漢不用加鎖

在 C11 及之后&#xff0c;“局部靜態變量懶漢”&#xff08;Meyers’ Singleton&#xff09;不需要自己加鎖&#xff0c;標準已經幫你做好了線程安全。 Singleton& getInstance() {static Singleton inst; // ← 這一句并發時只會初始化一次return inst; }首次調用時&am…

51單片機-GPIO介紹

本章概述思維導圖&#xff1a;51單片機引腳介紹STC89系列51單片機引腳介紹STC89系列51單片機的引腳是單片機與外部電路連接的接口&#xff0c;用于實現電源供電、時鐘信號輸入、控制信號輸出以及數據輸入輸出等功能。PDIP封裝引腳圖&#xff1a;1. 電源引腳&#xff1a;VCC&…

CERT/CC警告:新型HTTP/2漏洞“MadeYouReset“恐致全球服務器遭DDoS攻擊癱瘓

2025年8月15日CERT/CC&#xff08;計算機應急響應協調中心&#xff09;近日發布漏洞公告&#xff0c;警告多個HTTP/2實現中新發現的缺陷可能被威脅行為者用于發起高效拒絕服務&#xff08;DoS&#xff09;或分布式拒絕服務&#xff08;DDoS&#xff09;攻擊。該漏洞被非正式命名…

[Chat-LangChain] 會話圖(LangGraph) | 大語言模型(LLM)

第二章&#xff1a;會話圖&#xff08;LangGraph&#xff09; 在第一章中&#xff0c;我們學習了前端用戶界面——這是聊天機器人的"面孔"&#xff0c;我們在這里輸入問題并查看答案。 我們看到了消息如何從聊天窗口傳遞到聊天機器人的"大腦"。現在&…

Flask錯誤處理與會話技術詳解

flask入門day03 錯誤處理 1.abort函數&#xff1a;放棄請求并返回錯誤代碼 詳細狀態碼 from flask import Flask,abort,render_template ? app Flask(__name__) ? app.route(/) def index():return 我是首頁 ? app.route(/error) def error():abort(404)return 沒有找到…

java程序打包成exe,再打成安裝包,沒有jdk環境下可運行

一、前提條件準備&#xff1a;1、要被打包的程序文件&#xff1a;rest_assistant-1.0-SNAPSHOT.jarapplication.yml2、圖標文件tubiao123.ico3、jre4、打包成exe的軟件 config.exe4j5、打成安裝包的軟件 Inno Setup Compiler二、config.exe4j 的 exe打包配置步驟 按照以下圖進行…

區塊鏈技術原理(11)-以太坊交易

文章目錄什么是交易&#xff1f;交易類型交易生命周期關鍵概念&#xff1a;Gas 與交易費用交易狀態與失敗原因總結什么是交易&#xff1f; “交易&#xff08;Transaction&#xff09;” 是從一個賬戶向另一個賬戶發送的經過數字簽名的指令 。例如&#xff0c;如果 Bob 發送 A…

小兔鮮兒-小程序uni-app(二)

小兔鮮兒-小程序uni-app7.小兔鮮兒 - 用戶模塊會員中心頁(我的)靜態結構參考代碼會員設置頁分包預下載靜態結構退出登錄會員信息頁靜態結構獲取會員信息渲染會員信息更新會員頭像更新表單信息8.小兔鮮兒 - 地址模塊準備工作靜態結構地址管理頁地址表單頁動態設置標題新建地址頁…

BLE 廣播信道與數據信道:沖突避免、信道映射與自適應跳頻實現

低功耗藍牙(BLE)技術憑借低功耗、短距離、低成本的特性,已廣泛應用于智能家居、可穿戴設備、工業物聯網等領域。在 BLE 協議中,信道管理是保障通信可靠性的核心機制,其中廣播信道與數據信道的設計、沖突避免策略、跳頻技術更是面試中的高頻考點。本文將從基礎原理到實戰真…