gpt4 book ai didi

java - 如何从多个线程更新缓存

转载 作者:行者123 更新时间:2023-11-30 01:58:48 25 4
gpt4 key购买 nike

我有一个 Runnable,它有一个缓存(类型为 Cache ),我们假设它提供线程安全操作。这个Runnable对象被多个线程使用。

我们的线程从外部源获取对象,然后

  1. 检查缓存中是否存在对象键
  2. 如果没有,则放置
  3. 如果它已在缓存中,则更新

我正在寻找正确的方案(即最小的同步代码)来可靠地使用缓存。

我想出了以下方案:

    MyObject current = cache.getIfPresent(givenKey);
if (current == null) {
MyObject prev = cache.asMap().putIfAbsent(givenKey, givenObj);
if (prev == null) {
// successful put in cache
return givenObj;
}
}

// current != null or another thread update
synchronized (current) {
return update(current, givenObj); // in place change of current
}

我的方案背后的关键思想+可靠性“证明”:

  1. 如果线程在不同的键上工作,则无需阻塞
  2. 如果currentnull,那么由于缓存是线程安全的,只有一个线程能够将对象放入缓存中,而其他线程将看到上一个!= null
  3. 其他线程必须连续更新。请注意,我正在同步要更新的对象 current
<小时/>

问题

  1. 我的方案可靠吗?
  2. 可以优化吗?
  3. 在某些情况下,必须使用 volatile 来使内存同步可靠。我这里需要吗?

谢谢!

最佳答案

1)不,你的架构不可靠你不应该打电话

cache.asMap().putIfAbsent(givenKey, givenObj);

通过 guava 文档方法cache.get(K key, Callable loader) 比使用 asMap 方法更好。

2)是的,它可以优化您应该调用此方法:

cache.get(K key, Callable<? extends V> loader)

如果该值已在缓存中,则该方法将返回该值;如果该值不在缓存中,则该方法会将加载器中的值添加到缓存中并返回该值。

例如:

 MyObject objInCache =  cache.get(givenKey, ()->givenObj)

if(!objInCache.equals(givenobj)){
//obje was in the cache,
//update object
}

3)如果缓存是线程安全的,则不需要 volatile

关于java - 如何从多个线程更新缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53541483/

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