面试题答案
一键面试基于时间过期
Caffeine 支持两种基于时间的过期策略:写入后过期(expireAfterWrite)和访问后过期(expireAfterAccess)。
- 写入后过期(expireAfterWrite):
表示缓存项在被写入或更新后的指定时间后过期。
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.LoadingCache; import java.util.concurrent.TimeUnit; public class CaffeineExample { public static void main(String[] args) { LoadingCache<String, String> cache = Caffeine.newBuilder() .expireAfterWrite(5, TimeUnit.MINUTES) .build(key -> "default value for " + key); cache.put("key1", "value1"); // 在5分钟后,"key1" 对应的缓存项将过期 String value = cache.get("key1"); System.out.println(value); } }
- 访问后过期(expireAfterAccess):
表示缓存项在被访问(读或写)后的指定时间后过期。
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.LoadingCache; import java.util.concurrent.TimeUnit; public class CaffeineExample2 { public static void main(String[] args) { LoadingCache<String, String> cache = Caffeine.newBuilder() .expireAfterAccess(10, TimeUnit.SECONDS) .build(key -> "default value for " + key); cache.put("key1", "value1"); // 每次访问"key1",过期时间将重置,从最后一次访问开始10秒后过期 String value = cache.get("key1"); System.out.println(value); } }
基于访问频率过期
Caffeine 可以通过设置 eviction
策略来实现基于访问频率过期。eviction
策略可以通过 removalListener
来监听缓存项的移除事件,结合 accessOrder
来实现基于访问频率的过期。
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.RemovalCause;
import com.github.benmanes.caffeine.cache.RemovalListener;
import java.util.concurrent.TimeUnit;
public class CaffeineAccessFrequencyExample {
public static void main(String[] args) {
RemovalListener<String, String> removalListener = (key, value, cause) -> {
if (cause == RemovalCause.EVICTED) {
System.out.println("Evicted key: " + key + ", value: " + value);
}
};
Cache<String, String> cache = Caffeine.newBuilder()
.expireAfterWrite(1, TimeUnit.MINUTES)
.maximumSize(100)
.accessOrder(true)
.removalListener(removalListener)
.build();
cache.put("key1", "value1");
cache.put("key2", "value2");
// 访问key1
cache.getIfPresent("key1");
// 当缓存达到最大容量100时,最少访问的项会被移除
}
}
在上述代码中,accessOrder(true)
表示按照访问顺序(最不经常访问的优先被移除),结合 maximumSize
设置最大缓存项数量,当缓存达到最大数量时,最不经常访问的项会被移除。removalListener
用于监听缓存项的移除事件,这里主要关注因驱逐(RemovalCause.EVICTED
)而移除的情况。