Java高性能缓存库Caffeine

您所在的位置:网站首页 java中的缓存机制 Java高性能缓存库Caffeine

Java高性能缓存库Caffeine

2023-04-03 11:42| 来源: 网络整理| 查看: 265

Java高性能缓存库CaffeineCaffeine简介Caffeine基本使用缓存类型CacheLoadingCacheAsyncCacheAsyncLoadingCache驱逐策略刷新机制统计SpringBoot中集成CaffeineSpringBoot缓存管理器使用@Cacheable相关注解@Cacheable相关注解常用注解属性缓存同步模式Caffeine集成实战User结构缓存组件在控制器中使用缓存测试附录

Caffeine是基于Java的一个高性能本地缓存库,由Guava改进而来;

本文介绍了如何在Java中使用Caffeine缓存,以及如何在SpringBoot中集成Caffeine缓存;

源代码:

https://github.com/JasonkayZK/java-all/tree/main/cache/caffeine https://github.com/ben-manes/caffeine Java高性能缓存库CaffeineCaffeine简介

Caffeine是一个Java高性能的本地缓存库。其官方说明指出,其缓存命中率已经接近最优值。

实际上,Caffeine这样的本地缓存和ConcurrentMap很像:支持并发,并且支持O(1)时间复杂度的数据存取。二者的主要区别在于:

ConcurrentMap将存储所有存入的数据,直到你显式将其移除; Caffeine将通过给定的配置,自动移除“不常用”的数据,以保持内存的合理占用。

因此,一种更好的理解方式是:

Cache是一种带有存储和移除策略的Map

Caffeine提供如下的一些功能:

- automatic loading of entries into the cache, optionally asynchronously # 自动加载条目到缓存中,支持异步加载 - size-based eviction when a maximum is exceeded based on frequency and recency # 根据频率和最近访问情况,支持将缓存数量设为移除策略 - time-based expiration of entries, measured since last access or last write # 根据最近访问和修改时间,支持将时间设为移除策略 - asynchronously refresh when the first stale request for an entry occurs # 过期条目再次访问时异步加载 - keys automatically wrapped in weak references # key自动包装为弱引用 - values automatically wrapped in weak or soft references # value自动包装为弱引用/软引用 - notification of evicted (or otherwise removed) entries # 条目移除通知 - writes propagated to an external resource # 对外部资源的写入 - accumulation of cache access statistics # 累计缓存使用统计 Caffeine基本使用

在项目中添加依赖:

com.github.ben-manes.caffeine caffeine 2.9.3

本文基于 2.9.3 版本;

缓存类型

Caffeine提供了四种类型的Cache,对应着四种加载策略:

Cache; LoadingCache; AsyncCache; AsyncLoadingCache;

下面分别来看;

Cache

最普通的一种缓存,无需指定加载方式,需要手动调用put()进行加载;

需要注意的是:put()方法对于已存在的key将进行覆盖,这点和Map的表现是一致的;

在获取缓存值时,如果想要在缓存值不存在时,原子地将值写入缓存,则可以调用get(key, k -> value)方法,该方法将避免写入竞争;

调用invalidate()方法,将手动移除缓存;

多线程情况下,当使用get(key, k -> value)时,如果有另一个线程同时调用本方法进行竞争,则后一线程会被阻塞,直到前一线程更新缓存完成;

而若另一线程调用getIfPresent()方法,则会立即返回null,不会被阻塞;

cache/caffeine/basic/src/main/java/io/github/jasonkayzk/type/CacheDemo.java

public class CacheDemo { public static void main(String[] args) { Cache cache = Caffeine.newBuilder().build(); System.out.println(cache.getIfPresent("123")); // null System.out.println(cache.get("123", k -> "456")); // 456 System.out.println(cache.getIfPresent("123")); // 456 cache.put("123", "789"); System.out.println(cache.getIfPresent("123")); // 789 } } LoadingCache

LoadingCache是一种自动加载的缓存;

和普通缓存不同的地方在于:当缓存不存在/缓存已过期时,若调用get()方法,则会自动调用CacheLoader.load()方法加载最新值;

调用getAll()方法将遍历所有的key调用get(),除非实现了CacheLoader.loadAll()方法。

使用LoadingCache时,需要指定CacheLoader,并实现其中的load()方法供缓存缺失时自动加载。

多线程情况下,当两个线程同时调用get(),则后一线程将被阻塞,直至前一线程更新缓存完成。

cache/caffeine/basic/src/main/java/io/github/jasonkayzk/type/LoadingCacheDemo.java

public class LoadingCacheDemo { public static void main(String[] args) { LoadingCache cache = Caffeine.newBuilder() .build(new CacheLoader() { @Override // 该方法必须实现 public String load(@NonNull String k) throws Exception { return "456"; } @Override // 如果需要批量加载 public @NonNull Map loadAll(@NonNull Iterable


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3