Java TimedCache 帶時間緩存工具類詳解使用
簡述
我們在工作中會碰到需要使用帶過期時間的緩存場景。但是使用redis有太重了,畢竟緩存的數(shù)據(jù)很小,放在內(nèi)存夠夠的。hutools提供了TimedCache時間緩存工具,可以實現(xiàn)該場景。下面使用到該組件,并為了適配工作場景,對該工具類做優(yōu)化升級。
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);
}
/**
* 存入鍵值對,提供消逝時間
*
* @param key
* @param value
* @param timeout
*/
public static void put(String key, String value, Long timeout) {
/** 設置消逝時間 */
TIMED_CACHE.put(key, value, timeout);
}
/**
* 每次重新get一次緩存,均會重新刷新消逝時間
* @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次結果:" + get("haha"));
ThreadUtil.sleep(2000);
System.out.println("第2次結果:" + get("haha"));
ThreadUtil.sleep(5000);
System.out.println("第3次結果:" + get("haha"));
// 取消定時清理
TIMED_CACHE.cancelPruneSchedule();
}
}
首先我們看一下執(zhí)行的效果

說明:
1、設置的超時時間為3000毫秒,所以第一次打印在2秒鐘,所以可以獲取到值。
2、因為第一次打印調(diào)用了get方法,刷新了過期時間,所以依然可以獲取到值。
3、第三次打印在5秒后,所以已經(jīng)過期,無法獲取到值,打印null。
那么,需要知道是否緩存還在可以使用containsKey方法。如下:
put("haha", "1", 3000L);
ThreadUtil.sleep(2000);
if (TIMED_CACHE.containsKey("haha")) {
System.out.println("第1次結果:緩存存在");
}
// System.out.println("第1次結果:" + get("haha"));
ThreadUtil.sleep(2000);
System.out.println("第2次結果:" + get("haha"));
ThreadUtil.sleep(5000);
System.out.println("第3次結果:" + get("haha"));
// 取消定時清理
TIMED_CACHE.cancelPruneSchedule();
執(zhí)行結果如下:

工具優(yōu)化-監(jiān)聽過期、增加回調(diào)
我們在使用TimedCache會發(fā)現(xiàn),一旦緩存過期我們并不能立馬知道,很多工作場景中需要對緩存做監(jiān)聽回調(diào)。所以我升級了一下該工具類。
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: 時間緩存工具 */
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;
/**
* 存入鍵值對,添加過期時間,和消費回調(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"));
// 關閉監(jiān)聽線程池
listeningExecutorService.shutdown();
}
}
執(zhí)行結果:

說明:
1、可以看到監(jiān)聽到緩存過期,并進行了回調(diào)。
總結
具體的工具類使用場景,因項目而異,大家看著來。
如果本文對你有幫助,請點個贊支持一下吧。

到此這篇關于Java TimedCache 帶時間緩存工具類詳解使用的文章就介紹到這了,更多相關Java TimedCache內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
JPA findById方法和getOne方法的區(qū)別說明
這篇文章主要介紹了JPA findById方法和getOne方法的區(qū)別,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教。2021-08-08
基于springboot+jwt實現(xiàn)刷新token過程解析
這篇文章主要介紹了基于springboot+jwt實現(xiàn)刷新token過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-03-03
啟動SpringBoot報錯Input length = 1問題及解決
這篇文章主要介紹了啟動SpringBoot報錯Input length = 1問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05

