最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java使用map實現(xiàn)帶過期時間的緩存機制

 更新時間:2025年04月27日 08:29:06   作者:小太陽381  
在?Java?開發(fā)領(lǐng)域,緩存機制的構(gòu)建通常依賴于?Redis?等專業(yè)緩存數(shù)據(jù)庫,這類解決方案雖能提供強大的緩存能力,但引入中間件意味著增加系統(tǒng)架構(gòu)復(fù)雜度、部署成本與運維負(fù)擔(dān),本文將深入探討一種輕量級替代方案基于?Java?原生Map實現(xiàn)的帶過期時間的緩存機制

引言

在 Java 開發(fā)領(lǐng)域,緩存機制的構(gòu)建通常依賴于 Redis 等專業(yè)緩存數(shù)據(jù)庫。這類解決方案雖能提供強大的緩存能力,但引入中間件意味著增加系統(tǒng)架構(gòu)復(fù)雜度、部署成本與運維負(fù)擔(dān)。本文將深入探討一種輕量級替代方案 —— 基于 Java 原生Map實現(xiàn)的帶過期時間的緩存機制。該方案無需引入外部工具,僅依托 Java 標(biāo)準(zhǔn)庫即可快速搭建起緩存體系,特別適用于對資源占用敏感、架構(gòu)追求極簡的項目場景,為開發(fā)者提供了一種輕量高效的緩存數(shù)據(jù)管理新選擇。

優(yōu)點

  • 輕量便捷:無需引入 Redis 等外部中間件,直接使用 Java 標(biāo)準(zhǔn)庫即可實現(xiàn),降低了項目依賴,簡化了部署流程。
  • 快速搭建:基于熟悉的Map數(shù)據(jù)結(jié)構(gòu),開發(fā)人員能夠快速理解和實現(xiàn)緩存邏輯,顯著提升開發(fā)效率。
  • 資源可控:可靈活控制緩存數(shù)據(jù)的生命周期,通過設(shè)置過期時間,精準(zhǔn)管理內(nèi)存占用,適合對資源占用敏感的場景。

缺點:該方案存在明顯局限性,即數(shù)據(jù)無法持久化。一旦應(yīng)用程序停止運行,緩存中的所有數(shù)據(jù)都會丟失。相較于 Redis 等具備持久化功能的專業(yè)緩存數(shù)據(jù)庫,在需要長期保存緩存數(shù)據(jù),或是應(yīng)對應(yīng)用重啟后數(shù)據(jù)恢復(fù)需求的場景下,基于 Java 原生Map的緩存機制就顯得力不從心。

代碼實現(xiàn)

package com.sunny.utils;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class SysCache {

    // 單例實例
    private static class Holder {
        private static final SysCache INSTANCE = new SysCache();
    }

    public static SysCache getInstance() {
        return Holder.INSTANCE;
    }

    // 緩存存儲結(jié)構(gòu),Key為String,Value為包含值和過期時間的CacheEntry對象
    private final ConcurrentHashMap<String, CacheEntry> cacheMap = new ConcurrentHashMap<>();
    // 定時任務(wù)執(zhí)行器
    private final ScheduledExecutorService  scheduledExecutorService;

    // 私有構(gòu)造方法,初始化定時清理任務(wù)
    private SysCache() {
        scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        // 每隔1秒執(zhí)行一次清理任務(wù)
        scheduledExecutorService.scheduleAtFixedRate(this::cleanUp, 1, 1, TimeUnit.SECONDS);
        // 注冊JVM關(guān)閉鉤子以優(yōu)雅關(guān)閉線程池
        Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown));
    }

    /**
     * 存入緩存
     * @param key 鍵
     * @param value 值
     */
    public void set(String key, Object value){
        cacheMap.put(key, new CacheEntry(value, -1));
    }

    /**
     * 存入緩存
     * @param key 鍵
     * @param value 值
     * @param expireTime 過期時間,單位毫秒
     */
    public void set(String key, Object value, long expireTime) {
        if (expireTime <= 0) {
            throw new IllegalArgumentException("expireTime must be greater than 0");
        }
        cacheMap.put(key, new CacheEntry(value, System.currentTimeMillis() + expireTime));
    }

    /**
     * 刪除緩存
     * @param key 鍵
     */
    public void remove(String key) {
        cacheMap.remove(key);
    }

    /**
     * 緩存中是否包含鍵
     * @param key 鍵
     */
    public boolean containsKey(String key) {
        CacheEntry cacheEntry = cacheMap.get(key);
        if (cacheEntry == null) {
            return false;
        }
        if (cacheEntry.getExpireTime() < System.currentTimeMillis()) {
            remove(key);
            return false;
        }
        return true;
    }


    /**
     *獲取緩存值
     * @param key 鍵
     */
    public Object get(String key) {
        CacheEntry cacheEntry = cacheMap.get(key);
        if (cacheEntry == null) {
            return null;
        }
        if (cacheEntry.getExpireTime() < System.currentTimeMillis()) {
            cacheMap.remove(key);
            return null;
        }
        return cacheEntry.getValue();
    }


    private static class CacheEntry {
        private final Object value;
        private final long expireTime;

        public CacheEntry(Object value, long expireTime) {
            this.value = value;
            this.expireTime = expireTime;
        }

        public Object getValue() {
            return value;
        }

        public long getExpireTime() {
            return expireTime;
        }
    }

    /**
     * 定時清理過期條目
     */
    private void cleanUp() {
        Iterator<Map.Entry<String, CacheEntry>> iterator = cacheMap.entrySet().iterator();
        long currentTime = System.currentTimeMillis();
        while (iterator.hasNext()) {
            Map.Entry<String, CacheEntry> entry = iterator.next();
            CacheEntry cacheEntry = entry.getValue();
            if (cacheEntry.expireTime < currentTime) {
                // 使用iterator移除當(dāng)前條目,避免ConcurrentModificationException
                iterator.remove();
            }
        }
    }

    /**
     * 關(guān)閉線程池釋放資源
     */
    private void shutdown() {
        scheduledExecutorService.shutdown();
        try {
            if (!scheduledExecutorService.awaitTermination(5, TimeUnit.SECONDS)) {
                scheduledExecutorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            scheduledExecutorService.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
}

測試

如上圖,緩存中放入一個值,過期時間為5秒,每秒循環(huán)獲取1次,循環(huán)10次,過期后,獲取的值為null

到此這篇關(guān)于Java使用map實現(xiàn)帶過期時間的緩存機制的文章就介紹到這了,更多相關(guān)Java map過期時間緩存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決Maven多模塊編譯慢的問題

    解決Maven多模塊編譯慢的問題

    這篇文章主要介紹了Maven多模塊編譯慢的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java日期工具類操作字符串Date和LocalDate互轉(zhuǎn)

    Java日期工具類操作字符串Date和LocalDate互轉(zhuǎn)

    這篇文章主要介紹了Java日期工具類操作字符串Date和LocalDate互轉(zhuǎn),文章首先通過需要先引入坐標(biāo)展開主題的相關(guān)內(nèi)容介紹,需要的朋友可以參一下
    2022-06-06
  • spring security如何擴展自定義登錄

    spring security如何擴展自定義登錄

    本文詳細(xì)介紹了Spring Security的認(rèn)證原理和具體實現(xiàn),認(rèn)證原理基于過濾器鏈,通過驗證用戶憑證和構(gòu)建認(rèn)證對象來保護應(yīng)用程序資源,實現(xiàn)自定義認(rèn)證功能的步驟包括創(chuàng)建自定義認(rèn)證提供程序、實現(xiàn)UserDetailsService接口以及在配置類中進行相應(yīng)的配置
    2024-11-11
  • 淺談標(biāo)簽和JLabel類構(gòu)造方法

    淺談標(biāo)簽和JLabel類構(gòu)造方法

    這篇文章主要介紹了標(biāo)簽和JLabel類構(gòu)造方法,具有一定參考價值,需要的朋友可以參考下。
    2017-09-09
  • Java Socket實現(xiàn)簡易聊天室

    Java Socket實現(xiàn)簡易聊天室

    這篇文章主要為大家詳細(xì)介紹了Java Socket實現(xiàn)簡易聊天室,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • Java中的Sort排序問題

    Java中的Sort排序問題

    這篇文章主要介紹了Java中的Sort排序問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 使用Java8實現(xiàn)模板方法模式的改造

    使用Java8實現(xiàn)模板方法模式的改造

    這篇文章主要為大家詳細(xì)介紹了如何使用Java8實現(xiàn)模板方法模式的改造,文中的示例代碼講解詳細(xì),對我們深入了解java8有一定的幫助,感興趣的可以了了解一下
    2023-01-01
  • IDEA自定義常用代碼塊及自定義快捷摸板

    IDEA自定義常用代碼塊及自定義快捷摸板

    這篇文章主要介紹了IDEA自定義常用代碼塊及自定義快捷摸板的相關(guān)知識,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2020-09-09
  • 測量Java對象所占內(nèi)存大小方式

    測量Java對象所占內(nèi)存大小方式

    這篇文章主要介紹了測量Java對象所占內(nèi)存大小方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Java 十大排序算法之計數(shù)排序刨析

    Java 十大排序算法之計數(shù)排序刨析

    計數(shù)排序是一個非基于比較的排序算法,該算法于1954年由 Harold H. Seward 提出。它的優(yōu)勢在于在對一定范圍內(nèi)的整數(shù)排序時,它的復(fù)雜度為Ο(n+k)(其中k是整數(shù)的范圍),快于任何比較排序算法
    2021-11-11

最新評論

安丘市| 竹溪县| 桃园县| 辉南县| 延边| 太原市| 乐清市| 辽源市| 淳安县| 罗山县| 蒙阴县| 淅川县| 东兴市| 应城市| 辽源市| 金溪县| 唐山市| 巫山县| 庆城县| 南开区| 五原县| 建平县| 安乡县| 松桃| 论坛| 都江堰市| 彰武县| 诸暨市| 德阳市| 安康市| 淮阳县| 定结县| 罗田县| 万盛区| 清河县| 定安县| 繁峙县| 尼勒克县| 白玉县| 左权县| 景洪市|