Java中TimedCache緩存對象的詳細使用教程
一、TimedCache 是什么?
TimedCache是一個泛型類,它的主要作用通常是在一定時間范圍內(nèi)對特定鍵值對進行緩存,并且能夠根據(jù)設(shè)定的時間策略來自動清理過期的緩存項。
TimedCache是一種帶有時間控制功能的緩存數(shù)據(jù)結(jié)構(gòu)。在 Java 中,緩存是一種用于臨時存儲數(shù)據(jù)的機制,目的是為了減少重復計算或者重復的數(shù)據(jù)獲取操作,提高程序的性能。而TimedCache在此基礎(chǔ)上增加了時間維度的管理。
二、常見功能及使用場景
緩存存儲:可以將以String為鍵、BigDecimal為值的鍵值對存入緩存中,方便后續(xù)快速獲取,避免重復計算或查詢相同的數(shù)據(jù)。其它類型也可以。(理解為Map集合,鍵值對)
時間控制:設(shè)置緩存項的有效期,一旦超過指定時間,緩存項會被自動視為過期并可能被清理掉。這有助于保證緩存數(shù)據(jù)的時效性,例如在處理實時金融數(shù)據(jù)(如匯率、股票價格等,這里值用BigDecimal表示很合適)時,舊的數(shù)據(jù)在一定時間后就不再有價值,通過定時清理過期緩存可確保獲取到相對新的數(shù)據(jù)。
緩存獲取:通過給定的String鍵,可以快速從緩存中獲取對應的BigDecimal值,如果緩存命中則直接返回緩存中的值,提高數(shù)據(jù)訪問效率。
三、使用場景
金融數(shù)據(jù)處理:如前面提到的匯率、股票價格等數(shù)據(jù)的緩存。金融數(shù)據(jù)經(jīng)常需要實時更新,但在短時間內(nèi)可能會被多次查詢,使用TimedCache<String, BigDecimal>可以緩存這些數(shù)據(jù),在有效期內(nèi)直接從緩存獲取,減少對數(shù)據(jù)源(如金融數(shù)據(jù)接口)的頻繁訪問,提高系統(tǒng)響應速度。
電商價格緩存:在電商系統(tǒng)中,商品價格可能會根據(jù)促銷活動等因素實時變動,但在一定時間段內(nèi)(比如促銷活動期間),對于同一商品的價格查詢較為頻繁。將商品 ID(可以用String表示)作為鍵,商品價格(用BigDecimal表示)作為值存入TimedCache,可以在活動期間有效緩存價格數(shù)據(jù),提高查詢效率。
統(tǒng)計數(shù)據(jù)緩存:例如網(wǎng)站的實時流量統(tǒng)計數(shù)據(jù),以某個統(tǒng)計指標的名稱(String)為鍵,對應的統(tǒng)計數(shù)值(可能是BigDecimal類型,如流量的具體數(shù)值等)為值進行緩存。這樣在短時間內(nèi)可以快速獲取統(tǒng)計數(shù)據(jù),并且通過設(shè)置合適的時間限制,確保數(shù)據(jù)能及時更新。
四、使用
1、相關(guān)依賴
<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>
2、使用
2.1、自定義工具簡單使用:
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) { /** 設(shè)置消逝時間 */ 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次結(jié)果:" + get("haha")); ThreadUtil.sleep(2000); System.out.println("第2次結(jié)果:" + get("haha")); ThreadUtil.sleep(5000); System.out.println("第3次結(jié)果:" + get("haha")); // 取消定時清理 TIMED_CACHE.cancelPruneSchedule(); }
2.2、糊涂工具使用
CacheUtil具體方法:
/** * 緩存工具類 * @author Looly *@since 3.0.1 */ public class CacheUtil { /** * 創(chuàng)建FIFO(first in first out) 先進先出緩存. * * @param <K> Key類型 * @param <V> Value類型 * @param capacity 容量 * @param timeout 過期時長,單位:毫秒 * @return {@link FIFOCache} */ public static <K, V> FIFOCache<K, V> newFIFOCache(int capacity, long timeout){ return new FIFOCache<>(capacity, timeout); } /** * 創(chuàng)建FIFO(first in first out) 先進先出緩存. * * @param <K> Key類型 * @param <V> Value類型 * @param capacity 容量 * @return {@link FIFOCache} */ public static <K, V> FIFOCache<K, V> newFIFOCache(int capacity){ return new FIFOCache<>(capacity); } /** * 創(chuàng)建LFU(least frequently used) 最少使用率緩存. * * @param <K> Key類型 * @param <V> Value類型 * @param capacity 容量 * @param timeout 過期時長,單位:毫秒 * @return {@link LFUCache} */ public static <K, V> LFUCache<K, V> newLFUCache(int capacity, long timeout){ return new LFUCache<>(capacity, timeout); } /** * 創(chuàng)建LFU(least frequently used) 最少使用率緩存. * * @param <K> Key類型 * @param <V> Value類型 * @param capacity 容量 * @return {@link LFUCache} */ public static <K, V> LFUCache<K, V> newLFUCache(int capacity){ return new LFUCache<>(capacity); } /** * 創(chuàng)建LRU (least recently used)最近最久未使用緩存. * * @param <K> Key類型 * @param <V> Value類型 * @param capacity 容量 * @param timeout 過期時長,單位:毫秒 * @return {@link LRUCache} */ public static <K, V> LRUCache<K, V> newLRUCache(int capacity, long timeout){ return new LRUCache<>(capacity, timeout); } /** * 創(chuàng)建LRU (least recently used)最近最久未使用緩存. * * @param <K> Key類型 * @param <V> Value類型 * @param capacity 容量 * @return {@link LRUCache} */ public static <K, V> LRUCache<K, V> newLRUCache(int capacity){ return new LRUCache<>(capacity); } /** * 創(chuàng)建定時緩存. * * @param <K> Key類型 * @param <V> Value類型 * @param timeout 過期時長,單位:毫秒 * @return {@link TimedCache} */ public static <K, V> TimedCache<K, V> newTimedCache(long timeout){ return new TimedCache<>(timeout); } /** * 創(chuàng)建弱引用緩存. * * @param <K> Key類型 * @param <V> Value類型 * @param timeout 過期時長,單位:毫秒 * @return {@link WeakCache} * @since 3.0.7 */ public static <K, V> WeakCache<K, V> newWeakCache(long timeout){ return new WeakCache<>(timeout); } /** * 創(chuàng)建無緩存實現(xiàn). * * @param <K> Key類型 * @param <V> Value類型 * @return {@link NoCache} */ public static <K, V> NoCache<K, V> newNoCache(){ return new NoCache<>(); } }
Cache接口具體方法:
/** * 緩存接口 * * @param <K> 鍵類型 * @param <V> 值類型 * @author Looly, jodd */ public interface Cache<K, V> extends Iterable<V>, Serializable { /** * 返回緩存容量,{@code 0}表示無大小限制 * * @return 返回緩存容量,{@code 0}表示無大小限制 */ int capacity(); /** * 緩存失效時長, {@code 0} 表示沒有設(shè)置,單位毫秒 * * @return 緩存失效時長, {@code 0} 表示沒有設(shè)置,單位毫秒 */ long timeout(); /** * 將對象加入到緩存,使用默認失效時長 * * @param key 鍵 * @param object 緩存的對象 * @see Cache#put(Object, Object, long) */ void put(K key, V object); /** * 將對象加入到緩存,使用指定失效時長<br> * 如果緩存空間滿了,{@link #prune()} 將被調(diào)用以獲得空間來存放新對象 * * @param key 鍵 * @param object 緩存的對象 * @param timeout 失效時長,單位毫秒 */ void put(K key, V object, long timeout); /** * 從緩存中獲得對象,當對象不在緩存中或已經(jīng)過期返回{@code null} * <p> * 調(diào)用此方法時,會檢查上次調(diào)用時間,如果與當前時間差值大于超時時間返回{@code null},否則返回值。 * <p> * 每次調(diào)用此方法會刷新最后訪問時間,也就是說會重新計算超時時間。 * * @param key 鍵 * @return 鍵對應的對象 * @see #get(Object, boolean) */ default V get(K key) { return get(key, true); } /** * 從緩存中獲得對象,當對象不在緩存中或已經(jīng)過期返回Func0回調(diào)產(chǎn)生的對象 * <p> * 調(diào)用此方法時,會檢查上次調(diào)用時間,如果與當前時間差值大于超時時間返回{@code null},否則返回值。 * <p> * 每次調(diào)用此方法會刷新最后訪問時間,也就是說會重新計算超時時間。 * * @param key 鍵 * @param supplier 如果不存在回調(diào)方法,用于生產(chǎn)值對象 * @return 值對象 */ default V get(K key, Func0<V> supplier) { return get(key, true, supplier); } /** * 從緩存中獲得對象,當對象不在緩存中或已經(jīng)過期返回Func0回調(diào)產(chǎn)生的對象 * <p> * 調(diào)用此方法時,會檢查上次調(diào)用時間,如果與當前時間差值大于超時時間返回{@code null},否則返回值。 * <p> * 每次調(diào)用此方法會可選是否刷新最后訪問時間,{@code true}表示會重新計算超時時間。 * * @param key 鍵 * @param isUpdateLastAccess 是否更新最后訪問時間,即重新計算超時時間。 * @param supplier 如果不存在回調(diào)方法,用于生產(chǎn)值對象 * @return 值對象 */ V get(K key, boolean isUpdateLastAccess, Func0<V> supplier); /** * 從緩存中獲得對象,當對象不在緩存中或已經(jīng)過期返回{@code null} * <p> * 調(diào)用此方法時,會檢查上次調(diào)用時間,如果與當前時間差值大于超時時間返回{@code null},否則返回值。 * <p> * 每次調(diào)用此方法會可選是否刷新最后訪問時間,{@code true}表示會重新計算超時時間。 * * @param key 鍵 * @param isUpdateLastAccess 是否更新最后訪問時間,即重新計算超時時間。 * @return 鍵對應的對象 */ V get(K key, boolean isUpdateLastAccess); /** * 返回包含鍵和值得迭代器 * * @return 緩存對象迭代器 * @since 4.0.10 */ Iterator<CacheObj<K, V>> cacheObjIterator(); /** * 從緩存中清理過期對象,清理策略取決于具體實現(xiàn) * * @return 清理的緩存對象個數(shù) */ int prune(); /** * 緩存是否已滿,僅用于有空間限制的緩存對象 * * @return 緩存是否已滿,僅用于有空間限制的緩存對象 */ boolean isFull(); /** * 從緩存中移除對象 * * @param key 鍵 */ void remove(K key); /** * 清空緩存 */ void clear(); /** * 緩存的對象數(shù)量 * * @return 緩存的對象數(shù)量 */ int size(); /** * 緩存是否為空 * * @return 緩存是否為空 */ boolean isEmpty(); /** * 是否包含key * * @param key KEY * @return 是否包含key */ boolean containsKey(K key); /** * 設(shè)置監(jiān)聽 * * @param listener 監(jiān)聽 * @return this * @since 5.5.2 */ default Cache<K, V> setListener(CacheListener<K, V> listener){ return this; } }
使用:創(chuàng)建一個緩存對象,自動清理時間單位為毫秒,自動清理時間為3秒鐘
public static void main(String[] args) { TimedCache<String, BigDecimal> dataCache = CacheUtil.newTimedCache(3000); String k = "key"; BigDecimal v = new BigDecimal("100"); dataCache.put(k,v); System.out.println("第1次結(jié)果:" + dataCache.get(k)); ThreadUtil.sleep(2000); System.out.println("第2次結(jié)果:" + dataCache.get(k)); ThreadUtil.sleep(5000); System.out.println("第3次結(jié)果:" + dataCache.get(k)); System.out.println("第3次結(jié)果-get方法:" + dataCache.get(k, () -> v)); //使用此方法,如果為空值就把數(shù)據(jù)重新賦值并且返回 System.out.println("第4次結(jié)果:" + dataCache.get(k)); }
以上就是Java中TimedCache緩存對象的詳細使用教程的詳細內(nèi)容,更多關(guān)于Java TimedCache使用的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
ReentrantLock 非公平鎖實現(xiàn)原理詳解
這篇文章主要為大家介紹了ReentrantLock 非公平鎖實現(xiàn)原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12Spring\SpringBoot配置連接數(shù)據(jù)庫的方法
最近在學習SpringBoot,第一步就是要配置數(shù)據(jù)庫,本文詳細的介紹了Spring\SpringBoot配置連接數(shù)據(jù)庫的方法,有需要的朋友們下面隨著小編來一起學習學習吧2021-06-06JavaWeb response和request對象原理及實例解析
這篇文章主要介紹了JavaWeb response和request對象原理及實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-11-11從零開始讓你的Spring?Boot項目跑在Linux服務器
這篇文章主要給大家介紹了如何從零開始讓你的Spring?Boot項目跑在Linux服務器的相關(guān)資料,由于springboot是內(nèi)嵌了tomcat,所以可以直接將項目打包上傳至服務器上,需要的朋友可以參考下2021-11-11SpringMVC+Mybatis實現(xiàn)的Mysql分頁數(shù)據(jù)查詢的示例
本篇文章主要介紹了SpringMVC+Mybatis實現(xiàn)的Mysql分頁數(shù)據(jù)查詢的示例,具有一定的參考價值,有興趣的可以了解一下2017-08-08spring實現(xiàn)bean對象創(chuàng)建代碼詳解
這篇文章主要介紹了spring實現(xiàn)bean對象創(chuàng)建代碼詳解,具有一定借鑒價值,需要的朋友可以參考下2017-12-12Java實現(xiàn)平滑加權(quán)輪詢算法之降權(quán)和提權(quán)詳解
所有負載均衡的場景幾乎都會用到這個平滑加權(quán)輪詢算法,下面這篇文章主要給大家介紹了關(guān)于Java實現(xiàn)平滑加權(quán)輪詢算法之降權(quán)和提權(quán)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下2022-04-04