我有一個緩存,我使用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