写业务的时候经常需要缓存一些数据,比如从 Redis 拿回来的列表,没必要每次都去请求。
但又不想引入一个重量级的缓存框架,就自己撸了个基于 ConcurrentHashMap 的本地缓存扩展方法。
支持过期时间,线程安全,用起来一行搞定。
实现代码
# 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.TimeUnit
data class CacheItem<T>(val value: T, val expireAt: Long)
val localCache = ConcurrentHashMap<String, CacheItem<Any>>()
/**
* 一个通用的本地缓存获取数据的扩展方法。
* @param key 缓存键。
* @param expireAfterMillis 缓存项的有效期(毫秒),默认值为1小时。
* @param fetcher 在缓存未命中或数据过期时用于获取新数据的lambda表达式。
* @return 缓存或新获取的数据。
*/
inline fun <reified T> getFromCacheOrFetch(
key: String,
expireAfterMillis: Long = TimeUnit.HOURS.toMillis(1), // 设置默认的过期时间为1小时
fetcher: () -> T?
): T? {
val now = System.currentTimeMillis()
val cacheItem = localCache[key]
if (cacheItem != null && now < cacheItem.expireAt && cacheItem.value is T) {
return cacheItem.value as T
} else {
val newValue = fetcher()
if (newValue != null) {
localCache[key] = CacheItem(newValue as Any, now + expireAfterMillis)
}
return newValue
}
}
|
使用方法
#调用的时候传个 key 和获取数据的 lambda 就行,缓存命中直接返回,过期了自动重新拉取。
1
2
3
4
5
6
7
8
| fun getRandomDeviceProfile(expireAfterMillis: Long = TimeUnit.MINUTES.toMillis(10)): String? {
val key="XHS:DeviceProfileList"
val randomResult=getFromCacheOrFetch(key, expireAfterMillis) {
// 这里是你的数据获取逻辑
getAllListValues(key)
}
return randomResult?.randomOne()
}
|