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

