Caffeine實(shí)現(xiàn)類似redis的動(dòng)態(tài)過(guò)期時(shí)間設(shè)置示例
使用Caffeine實(shí)現(xiàn)緩存功能
為了替換原有的redis接口,發(fā)現(xiàn)存在一個(gè)問(wèn)題:
原本的redis支持set(key, value, expire)這樣的功能,而原始的caffeine只能全局設(shè)置過(guò)期策略,不支持類似的功能,因此需要對(duì)Caffeine包裝一下,做了一個(gè)工具類實(shí)現(xiàn)類似redis的動(dòng)態(tài)過(guò)期時(shí)間設(shè)置。
工具類實(shí)現(xiàn)類似redis
import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Expiry; import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.nullness.qual.NonNull; import org.springframework.stereotype.Component; import java.util.Collection; import java.util.concurrent.TimeUnit; import static java.util.Objects.isNull; /** * 工具類 * * @author guo */ public class CacheUtils { /** * 不設(shè)置過(guò)期時(shí)長(zhǎng) */ public static final long NOT_EXPIRE = Long.MAX_VALUE; public static final Cache<String, CacheObject<?>> CAFFEINE = Caffeine.newBuilder() .expireAfter(new Expiry<String, CacheObject<?>>() { @Override public long expireAfterCreate(@NonNull String key, @NonNull CacheObject<?> value, long currentTime) { return value.expire; } @Override public long expireAfterUpdate(@NonNull String key, @NonNull CacheObject<?> value, long currentTime, @NonNegative long currentDuration) { return value.expire; } @Override public long expireAfterRead(@NonNull String key, @NonNull CacheObject<?> value, long currentTime, @NonNegative long currentDuration) { return value.expire; } }) .initialCapacity(100) .maximumSize(1024) .build(); private static class CacheObject<T> { T data; long expire; public CacheObject(T data, long second) { this.data = data; this.expire = TimeUnit.SECONDS.toNanos(second); } } public static <T> void set(String key, T value, long expire) { CacheObject<T> cacheObject = new CacheObject<>(value, expire); CAFFEINE.put(key, cacheObject); } public static void set(String key, Object value) { set(key, value, NOT_EXPIRE); } @SuppressWarnings("unchecked") public static <T> T get(String key) { CacheObject<?> cacheObject = CAFFEINE.getIfPresent(key); if (isNull(cacheObject)) { return null; } return (T) cacheObject.data; } public static void delete(String key) { CAFFEINE.invalidate(key); } public static void delete(Collection<String> keys) { CAFFEINE.invalidateAll(keys); } public static void main(String[] args) throws InterruptedException { CacheUtils.set("A", 1, 2); CacheUtils.set("B", 2, 5); CacheUtils.set("C", 3, 8); System.out.println(CAFFEINE.asMap()); Object a = CacheUtils.get("A"); Object b = CacheUtils.get("B"); Object c = CacheUtils.get("C"); System.out.println(a); System.out.println(b); System.out.println(c); System.out.println("-----------------"); Thread.sleep(2000); a = CacheUtils.get("A"); b = CacheUtils.get("B"); c = CacheUtils.get("C"); System.out.println(a); System.out.println(b); System.out.println(c); System.out.println("-----------------"); Thread.sleep(5000); a = CacheUtils.get("A"); b = CacheUtils.get("B"); c = CacheUtils.get("C"); System.out.println(a); System.out.println(b); System.out.println(c); System.out.println("-----------------"); Thread.sleep(8000); a = CacheUtils.get("A"); b = CacheUtils.get("B"); c = CacheUtils.get("C"); System.out.println(a); System.out.println(b); System.out.println(c); System.out.println("-----------------"); } }
以上就是Caffeine實(shí)現(xiàn)類似redis的動(dòng)態(tài)過(guò)期時(shí)間設(shè)置示例的詳細(xì)內(nèi)容,更多關(guān)于Caffeine動(dòng)態(tài)過(guò)期時(shí)間設(shè)置的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Redis中ServiceStack.Redis和StackExchange.Redis區(qū)別詳解
本文主要介紹了Redis中ServiceStack.Redis和StackExchange.Redis區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05Redis數(shù)據(jù)庫(kù)的使用場(chǎng)景介紹(避免誤用Redis)
這篇文章主要介紹了Redis數(shù)據(jù)庫(kù)的使用場(chǎng)景介紹(避免誤用Redis),本文用簡(jiǎn)要的語(yǔ)言總結(jié)了Redis數(shù)據(jù)庫(kù)的適應(yīng)場(chǎng)合,人而避免錯(cuò)誤的使用它而產(chǎn)生昂貴的維護(hù)代價(jià),需要的朋友可以參考下2015-03-03關(guān)于使用IDEA的springboot框架往Redis里寫入數(shù)據(jù)亂碼問(wèn)題
這篇文章主要介紹了用IDEA的springboot框架往Redis里寫入數(shù)據(jù)亂碼問(wèn)題,本文給大家分享解決方法通過(guò)圖文示例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10使用redis分布式鎖解決并發(fā)線程資源共享問(wèn)題
這篇文章主要介紹了使用redis分布式鎖解決并發(fā)線程資源共享問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07基于Redis的分布式鎖的簡(jiǎn)單實(shí)現(xiàn)方法
這篇文章主要介紹了基于Redis的分布式鎖的簡(jiǎn)單實(shí)現(xiàn)方法,Redis官方給出兩種思路,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10redis實(shí)現(xiàn)分布式延時(shí)隊(duì)列的示例代碼
延時(shí)隊(duì)列是一種特殊的消息隊(duì)列,它允許將消息在一定的延遲時(shí)間后再進(jìn)行消費(fèi),延時(shí)隊(duì)列的實(shí)現(xiàn)方式可以有多種,本文主要來(lái)介紹一種redis實(shí)現(xiàn)的分布式延時(shí)隊(duì)列,希望對(duì)大家有所幫助2023-10-10Redis 對(duì)過(guò)期數(shù)據(jù)的處理方法
這篇文章主要介紹了Redis 對(duì)過(guò)期數(shù)據(jù)的處理,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10Redis不是一直號(hào)稱單線程效率也很高嗎,為什么又采用多線程了?
這篇文章主要介紹了Redis不是一直號(hào)稱單線程效率也很高嗎,為什么又采用多線程了的相關(guān)資料,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03