Java TimedCache 帶時(shí)間緩存工具類詳解使用
簡述
我們?cè)诠ぷ髦袝?huì)碰到需要使用帶過期時(shí)間的緩存場景。但是使用redis有太重了,畢竟緩存的數(shù)據(jù)很小,放在內(nèi)存夠夠的。hutools提供了TimedCache時(shí)間緩存工具,可以實(shí)現(xiàn)該場景。下面使用到該組件,并為了適配工作場景,對(duì)該工具類做優(yōu)化升級(jí)。
Maven依賴
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.4.6</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.1.1-jre</version> </dependency>
簡單使用
不多說了,上代碼。
import cn.hutool.cache.CacheUtil; import cn.hutool.cache.impl.TimedCache; import cn.hutool.core.thread.ThreadUtil; /** @Author huyi @Date 2021/10/12 17:00 @Description: */ public class TimedCacheUtils { private static final TimedCache<String, String> TIMED_CACHE = CacheUtil.newTimedCache(5000); static { /** 每5ms檢查一次過期 */ TIMED_CACHE.schedulePrune(5); } /** * 存入鍵值對(duì),提供消逝時(shí)間 * * @param key * @param value * @param timeout */ public static void put(String key, String value, Long timeout) { /** 設(shè)置消逝時(shí)間 */ TIMED_CACHE.put(key, value, timeout); } /** * 每次重新get一次緩存,均會(huì)重新刷新消逝時(shí)間 * @param key * @return */ public static String get(String key) { return TIMED_CACHE.get(key); } public static void main(String[] args) { put("haha", "1", 3000L); ThreadUtil.sleep(2000); // if (TIMED_CACHE.containsKey("haha")) { // System.out.println("aa"); // } System.out.println("第1次結(jié)果:" + get("haha")); ThreadUtil.sleep(2000); System.out.println("第2次結(jié)果:" + get("haha")); ThreadUtil.sleep(5000); System.out.println("第3次結(jié)果:" + get("haha")); // 取消定時(shí)清理 TIMED_CACHE.cancelPruneSchedule(); } }
首先我們看一下執(zhí)行的效果
說明:
1、設(shè)置的超時(shí)時(shí)間為3000毫秒,所以第一次打印在2秒鐘,所以可以獲取到值。
2、因?yàn)榈谝淮未蛴≌{(diào)用了get方法,刷新了過期時(shí)間,所以依然可以獲取到值。
3、第三次打印在5秒后,所以已經(jīng)過期,無法獲取到值,打印null。
那么,需要知道是否緩存還在可以使用containsKey方法。如下:
put("haha", "1", 3000L); ThreadUtil.sleep(2000); if (TIMED_CACHE.containsKey("haha")) { System.out.println("第1次結(jié)果:緩存存在"); } // System.out.println("第1次結(jié)果:" + get("haha")); ThreadUtil.sleep(2000); System.out.println("第2次結(jié)果:" + get("haha")); ThreadUtil.sleep(5000); System.out.println("第3次結(jié)果:" + get("haha")); // 取消定時(shí)清理 TIMED_CACHE.cancelPruneSchedule();
執(zhí)行結(jié)果如下:
工具優(yōu)化-監(jiān)聽過期、增加回調(diào)
我們?cè)谑褂肨imedCache會(huì)發(fā)現(xiàn),一旦緩存過期我們并不能立馬知道,很多工作場景中需要對(duì)緩存做監(jiān)聽回調(diào)。所以我升級(jí)了一下該工具類。
import cn.hutool.cache.CacheUtil; import cn.hutool.cache.impl.TimedCache; import cn.hutool.core.thread.ThreadUtil; import com.google.common.util.concurrent.*; import org.checkerframework.checker.nullness.qual.Nullable; import java.text.MessageFormat; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Consumer; /** @Author huyi @Date 2021/10/12 10:57 @Description: 時(shí)間緩存工具 */ public class TimedCacheUtils { private static final TimedCache<String, String> TIMED_CACHE = CacheUtil.newTimedCache(5000); /** 線程池 */ private static final ExecutorService executorService = Executors.newCachedThreadPool(); private static final ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(executorService); /** 回調(diào)方法映射 */ private static ConcurrentHashMap<String, Consumer<String>> callbackMap; /** * 存入鍵值對(duì),添加過期時(shí)間,和消費(fèi)回調(diào) * * @param key * @param timeout * @param consumer */ public static void put(String key, String value, Long timeout, Consumer<String> consumer) { TIMED_CACHE.put(key, value, timeout); addListen(key, consumer); } /** * 獲取緩存值 * * @param key * @return */ public static String get(String key) { return TIMED_CACHE.get(key); } /** * 刪除緩存和回調(diào)映射 * * @param key */ public static void remove(String key) { callbackMap.remove(key); TIMED_CACHE.remove(key); } /** * 添加監(jiān)聽器 * * @param key * @param consumer */ public static void addListen(String key, Consumer<String> consumer) { ListenableFuture<String> listenableFuture = listeningExecutorService.submit( () -> { while (TIMED_CACHE.containsKey(key)) { ThreadUtil.sleep(500); } return key; }); Futures.addCallback( listenableFuture, new FutureCallback<String>() { @Override public void onSuccess(@Nullable String s) { consumer.accept(s); } @Override public void onFailure(Throwable throwable) { throwable.printStackTrace(); } }, listeningExecutorService); } public static void main(String[] args) { put("haha", "1", 3000L, x -> System.out.println(MessageFormat.format("[{0}] - 緩存消逝", x))); ThreadUtil.sleep(2000); System.out.println(get("haha")); ThreadUtil.sleep(2000); System.out.println(get("haha")); ThreadUtil.sleep(5000); System.out.println(get("haha")); // 關(guān)閉監(jiān)聽線程池 listeningExecutorService.shutdown(); } }
執(zhí)行結(jié)果:
說明:
1、可以看到監(jiān)聽到緩存過期,并進(jìn)行了回調(diào)。
總結(jié)
具體的工具類使用場景,因項(xiàng)目而異,大家看著來。
如果本文對(duì)你有幫助,請(qǐng)點(diǎn)個(gè)贊支持一下吧。
到此這篇關(guān)于Java TimedCache 帶時(shí)間緩存工具類詳解使用的文章就介紹到這了,更多相關(guān)Java TimedCache內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Servlet和Filter之間的區(qū)別與聯(lián)系
這篇文章主要介紹了Servlet和Filter之間的區(qū)別與聯(lián)系的相關(guān)資料,需要的朋友可以參考下2016-05-05Java實(shí)現(xiàn)Excel轉(zhuǎn)PDF的兩種方法詳解
使用具將Excel轉(zhuǎn)為PDF的方法有很多,在這里我給大家介紹兩種常用的方法:使用spire轉(zhuǎn)化PDF、使用jacob實(shí)現(xiàn)Excel轉(zhuǎn)PDF,分別應(yīng)對(duì)兩種不一樣的使用場景,需要的可以參考一下2022-01-016種Java創(chuàng)建對(duì)象的方式總結(jié)
在Java中,創(chuàng)建對(duì)象可以使用多種方式,本文將詳細(xì)介紹以下六種創(chuàng)建對(duì)象的方式,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2023-04-04JavaWeb Struts文件上傳功能實(shí)現(xiàn)詳解
這篇文章主要為大家詳細(xì)介紹了JavaWeb Struts文件上傳功能實(shí)現(xiàn)過程,思路清晰,供大家參考,感興趣的小伙伴們可以參考一下2016-06-06SpringBoot手動(dòng)開啟事務(wù):DataSourceTransactionManager問題
這篇文章主要介紹了SpringBoot手動(dòng)開啟事務(wù):DataSourceTransactionManager問題,具有很好的價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07