gpt4 book ai didi

java - Guava 缓存,如何在删除时阻止访问

转载 作者:行者123 更新时间:2023-11-29 05:17:37 24 4
gpt4 key购买 nike

我有线程 A,向 Guava Cache 插入一个新元素,并且由于 Size 策略,缓存将逐出与键 Y 关联的元素。

不幸的是,Y 的移除过程 R 需要很长时间,并且在 Y 被 R 处理的过程中(已经被驱逐但仍在 R 中),有另一个线程 B 试图获取与 key Y 关联的数据。

基本上,R 将尝试为键 Y 更新数据库,而当该值未更新时,线程 B 尝试访问数据库以获取与键 Y 关联的值,该值仍然是旧值。

问题是:当 R 正在工作时,如何阻止线程 B 访问具有键 Y 的元素?

最佳答案

你说的是Guava Cache,但是没有代码示例,所以我给出一个笼统的答案。

对于下面的内容,我假设您有一个“加载缓存”又名“自填充缓存”架构。

解决方案 1:正确设计您的缓存交互和数据库事务。

一旦在其上启动事务,更新过程就会使缓存条目无效。

  begin transaction
touch some of the entry data with SQL UPDATE to have it in the transaction
remove the entry from the cache
....
now you can do more operations on the database regarding the entry data
if you have the proper isolation level, reads from the database will stall
until the transaction is committed
....
end transaction

如果您从缓存中删除条目然后启动事务,则会引入竞争条件。

解决方案 2:使用缓存来阻止对同一键/条目的并发操作。

看看ehcache Blocking Cache .或者看看 cache2k其中阻塞行为是默认的。

但是,但是,您需要自己在加载程序级别上进行额外的锁定。例如。就像下面的例子。

解决方案 3:自己在缓存之上进行锁定并包装所有缓存操作。例如。像这样:

 Cache cache;
Lock[] locks = new Lock[16];
{ /* initialize locks */ }

public Object get(Object key) {
int idx = key.hashCode() % locks.length;
locks[idx].lock();
try { return cache.get(key);
} finally { locks[idx].unlock(); }
}

public void update(Object key, Object obj) {
int idx = key.hashCode() % locks.length;
locks[idx].lock();
try { return cache.put(key, obj);
} finally { locks[idx].unlock(); }
}

您还可以查看 ehcache 的 BlockingCache 实现并从中获得一些灵感。

玩得开心!

关于java - Guava 缓存,如何在删除时阻止访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25969983/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com