当负载执行时调用无效时,Google Guava LoadingCache会执行什么操作?

时间:2012-10-14 16:33:05

标签: caching concurrency guava

我有一个Google番石榴缓存,它从数据库加载数据并使用主键缓存它。我最终从数据库创建的对象是不可变的,构建对象需要访问多个表。在以下场景中会发生什么:

  • 线程1:调用cache.load(10)并根据值为10的数据库主键填充缓存
  • 线程2:使用主键10更新数据库行,因此它调用cache.invalidate(10)在cache.load(10)完成之前调用invalidate。

当load(x)执行时调用invalidate(x)时,Guava Loading Cache会做什么?

2 个答案:

答案 0 :(得分:6)

正如the Javadoc中当前指定的那样“在加载完成之前,不会修改与此高速缓存关联的可观察状态”。加载的语义进一步指定为“在加载完成后使用Cache.asMap().putIfAbsent将新加载的值添加到缓存中。”

您还可以阅读the code以查看在调用invalidate或remove时忽略加载条目的位置。

答案 1 :(得分:3)

你可以有两种情况:

  • 线程1首先到达实际加载点({13}中的LocalCache.Segment.lockedGetOrLoad()),并且段锁定为acquired:在这种情况下,加载完成,锁定为released并且计算的值将返回给调用者,但是当它运行时(LocalCache.Segment.remove())并且可以acquire锁定它将被线程2无效。

  • 线程2在线程1实际开始加载之前获取了锁:失效并没有真正做任何事情,因为条目还没有,然后线程1加载最新的值。