我有一个缓存,我使用simeple HashMap实现。像 -Java多线程原子参考分配
HashMap<String,String> cache = new HashMap<String,String>();
此缓存大部分时间用于从中读取值。我有另一种重新加载缓存的方法,并在这个方法里面我基本上创建一个新的缓存,然后分配引用。据我所知,对象引用的赋值是Java中的Atomic。
public class myClass {
private HashMap<String,String> cache = null;
public void init() {
refreshCache();
}
// this method can be called occasionally to update the cache.
public void refreshCache() {
HashMap<String,String> newcache = new HashMap<String,String>();
// code to fill up the new cache
// and then finally
cache = newcache; //assign the old cache to the new one in Atomic way
}
}
我明白,如果我不申报缓存中挥发,其他线程将无法看到的变化,但它不是时间关键我使用的情况下传播的高速缓存给其他线程,它们的变化可以继续使用旧缓存以延长时间。
您是否看到任何线程问题?考虑到许多线程正在从缓存中读取数据,并且只有在缓存重新载入的时候。
编辑- 我的主要困惑是我不必在这里使用AtomicReference作为赋值操作本身是原子吗?
编辑 - 我明白,要使排序正确,我应该将缓存标记为volatile。 但是,如果refreshCache方法标记为synchronized,那么我不必将缓存设置为volatile,因为Synchronized块会照顾排序和可见性?
为了简单的缓存目的,我通常使用* ConcurrentHashMap *并且不用担心锁定。我通常不关心一个(引用透明的)计算是否发生两次(也就是说,因为线程B开始计算与线程A当前正在计算的值相同的值,因此尚未放入缓存)。在你的情况下,我还会让* cache *成为* volatile *。但我没有看到“刷新缓存”的重点。使你的缓存成为一个LRU/MRU,并简单地向它添加新的缓存值,而不是“重置”它。 – SyntaxT3rr0r 2011-03-15 05:32:15
至少使用新映射刷新缓存允许使用非阻塞缓存映射实现 – ThomasRS 2012-04-19 11:31:52