Javamultithreadingprimefaces引用赋值

我有一个缓存,我使用simeple HashMap实现。 喜欢 –

HashMap cache = new HashMap(); 

大多数时候使用此缓存从中读取值。 我有另一个方法重新加载缓存,在这个方法内部我基本上创建一个新的缓存,然后分配引用。 据我所知,对象引用的赋值是Java中的Atomic。

 public class myClass { private HashMap cache = null; public void init() { refreshCache(); } // this method can be called occasionally to update the cache. public void refreshCache() { HashMap newcache = new HashMap(); // code to fill up the new cache // and then finally cache = newcache; //assign the old cache to the new one in Atomic way } } 

我理解如果我不将缓存声明为volatile,其他线程将无法看到更改,但对于我的用例来说,将缓存中的更改传播到其他线程并不是时间关键,并且它们可以继续使用旧缓存延长时间。

你看到任何线程问题吗? 考虑到许multithreading正在从缓存中读取,并且有时只重新加载缓存。

编辑 – 我的主要困惑是我不必在这里使用AtomicReference,因为赋值操作本身就是primefaces的?

编辑 – 我理解为了使顺序正确,我应该将缓存标记为volatile。 但是如果refreshCache方法被标记为synchronized,我不必将缓存设置为volatile,因为Synchronized块将负责排序和可见性?

没有适当的记忆障碍是不安全的。

有人会认为在填充缓存的步骤之后会发生缓存(cache = newCache)的分配。 但是,其他线程可能会遭受这些语句的重新排序,因此分配可能在填充缓存之前发生。 因此,可以在完全构造之前获取新缓存,甚至可以看到ConcurrentModificationException。

您需要强制执行before-before关系以防止此重新排序,并将缓存声明为volatile将实现此目的。

您应该将缓存标记为volatile

虽然您注意到其他线程可能会“长时间”继续使用陈旧缓存,但您应该注意到,如果没有同步边缘,它们可能会永远继续使用陈旧缓存。 这可能不是理想的行为。

按优先顺序排列(主要是由于可读性):

  • 以同步方法更新字段
  • 使用AtomicReference>
  • 使用volatile

另见这个问题 。

那么CopyOnWrite ..集合:

 java.util.concurrent.CopyOnWriteArraySet java.util.concurrent.CopyOnWriteArraySet and org.apache.mina.util.CopyOnWriteMap 

它们在您的情况下可以很好地匹配,并且它们是线程安全的。

似乎没问题。 确保不会过于频繁地调用refreshCache或将其标记为已synchronized