0

我正在使用它来创建我的缓存:

Cache<Long, Info> cache = newBuilder()
                .expireAfterWrite(getCacheMaxNbDays(), DAYS)
                .maximumSize(getCacheMaxSize())
                .build();

我想知道当我调用 cache.asMap() 并且正在执行一些条目驱逐时会发生什么。cache.asMap() 将等到驱逐操作完成,或者它只返回那些没有执行驱逐的条目?

我的第二个问题是:expireAfterWrite 是阻塞操作吗?换句话说,当对相同条目的读、写和逐出操作(expireAfterWrite、expireAfterAccess 等)之间存在并发时,咖啡因是如何工作的?

4

1 回答 1

0

缓存是建立在其之上的,ConcurrentHashMap因此它的大部分行为都适用。这包括无锁读取和写入的细粒度锁定。computeIfAbsent 调用样式可能是读取或写入,具体取决于条目是否存在,因此它可能会阻塞。该asMap()调用只是一个视图,因此无需等待或开销即可获得它。

通过 a 执行驱逐Map.compute,这将阻止对该条目的其他写入。当计算正在进行时,读取将观察条目,并且在完成后不会。

读取将验证条目是否未过期,如果未过期,则模拟缓存未命中以避免返回过时的结果。如果这是一种computeIfAbsent调用,那么它的加载器将替换过期的条目,处理通知等。由于另一个线程可能并行地试图驱逐它,每个条目的锁定将使其全部原子化,而失败者会优雅地处理它。

过期的条目是不可用的,所以如果加载调用会导致阻塞。该refreshAfterWrite设置可以与过期相结合,以隐藏在呼叫等待新负载时具有周期性延迟峰值的活动内容的惩罚。当条目有资格刷新但尚未过期时,下一次后续读取将触发后台重新加载。相反,如果在刷新间隔内没有访问该条目,那么它将过期并被驱逐。通过这种方式,活动内容保持新鲜和快速,同时允许非活动内容逐渐消失。

于 2021-11-17T19:35:52.797 回答