我正在編寫一個Web服務,嚴重依賴於每小時完全更新一次的單個大型地圖。剩下的時間很多線程同時讀取表格。併發只讀HashMap
我的問題是:什麼是實現這樣一個Map最有效的構造?
該地圖可能更大(100 - 500 MB)。除了整個地圖被替換一小時之外,只有讀取權限。
我正在考慮只使用Java HashMap,也許使用反射設置更新之間的字段最終如果這可以提高性能,但我不知道如何使JVM優化許多併發讀取。
我正在編寫一個Web服務,嚴重依賴於每小時完全更新一次的單個大型地圖。剩下的時間很多線程同時讀取表格。併發只讀HashMap
我的問題是:什麼是實現這樣一個Map最有效的構造?
該地圖可能更大(100 - 500 MB)。除了整個地圖被替換一小時之外,只有讀取權限。
我正在考慮只使用Java HashMap,也許使用反射設置更新之間的字段最終如果這可以提高性能,但我不知道如何使JVM優化許多併發讀取。
由於地圖在使用時未更新,請使用HashMap
,這可以提供出色的O(1)查找性能(犧牲線程安全性)。
當需要刷新時,建立一個新的映射和交換引用。
考慮使用AtomicReference
使交換線程安全:
private final AtomicReference<Map<K, V>> mapRef = new AtomicReference<>();
要使用:
mapRef.get().get(key);
初始化或換一個新的地圖:
Map<K, V> newMap = new HashMap<>();
// populate map
mapRef.set(newMap); // all threads will see this change
謝謝,這也是我考慮過的事情!但是,你能解釋一下你使用「AtomicReference」的意思嗎? – xgb84j
在你在你證明Java的標準HashMap速度不夠快之前,我認爲你可能需要使用它如果在這裏停止世界,可能會造成垃圾收集,可能會造成問題。
您可以通過總是重複使用HashMap(不要每次創建一個新的地圖)並預先分配存儲在地圖中的所有對象並重復使用它們來避免此問題。
除此之外,你可以通過使用兩個HashMaps來更快地完成替換,就像@Bohemian在他的回答中所暗示的那樣。
使用此。
public class Model {
private Map<?, ?> values;
private ReadWriteLock lock = new ReentrantReadWriteLock();
public ? getValue(? key) {
lock.readLock().lock();
? rv = values.get(key);
lock.readLock().unlock();
return rv;
}
public void update(Map<?, ?> values) {
lock.writeLock().lock();
rv = values;
//OR rv.putAll(values)
lock.writeLock().unlock();
}
}
前往ConcurrentHashMap。它允許併發讀取訪問而不影響性能。
http://stackoverflow.com/questions/1378310/performance-concurrenthashmap-vs-hashmap – dierre
訪問可以通過'ReadWriteLock'從外部管理。除此之外,你是否打算使它比「正常」的HashMap更有效率? – Marco13
你有沒有證據表明正常的HashMap是不夠的? –
我最害怕的是每個線程都有自己的副本。另外我讀了ConcurrentHashMap對於併發寫入的優點。 – xgb84j