2 回答

TA貢獻(xiàn)1874條經(jīng)驗(yàn) 獲得超12個贊
我不確定您是否需要地圖中的所有數(shù)據(jù),或者地圖中不再需要的計(jì)時器作業(yè)處理的數(shù)據(jù)。
如果您只需要計(jì)時器作業(yè)的快照之類的東西,您可以像這樣用新地圖切換/替換地圖。
private volatile ConcurentHashMap map ;
public void processByTimerJob(){
ConcurentHashMap oldMap = this.map;
this.map = new ConcurrentHashMap; // everyting new will be stored in new map
oldMap.forEach(..... //process old map via iteration or whatever you want
}

TA貢獻(xiàn)1789條經(jīng)驗(yàn) 獲得超10個贊
我會使用double buffering和讀/寫鎖。
雙緩沖通過允許處理換出的映射來減少阻塞。
使用讀/寫鎖讓我可以確定在我們交換后沒有人仍在寫入地圖。
class DoubleBufferedMap<K, V> extends AbstractMap<K, V> implements Map<K, V> {
// Used whenever I want to create a new map.
private final Supplier<Map<K, V>> mapSupplier;
// The underlying map.
private volatile Map<K, V> map;
// My lock - for ensuring no-one is writing.
ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
final Lock readLock = readWriteLock.readLock();
final Lock writeLock = readWriteLock.writeLock();
public DoubleBufferedMap(Supplier<Map<K, V>> mapSupplier) {
this.mapSupplier = mapSupplier;
this.map = mapSupplier.get();
}
/**
* Swaps out the current map with a new one.
*
* @return the old map ready for processing, guaranteed to have no pending writes.
*/
public Map<K,V> swap() {
// Grab the existing map.
Map<K,V> oldMap = map;
// Replace it.
map = mapSupplier.get();
// Take a write lock to wait for all `put`s to complete.
try {
writeLock.lock();
} finally {
writeLock.unlock();
}
return oldMap;
}
// Put methods must take a read lock (yeah I know it's weird)
@Nullable
@Override
public V put(K key, V value) {
try{
// Take a read-lock so they know when I'm finished.
readLock.lock();
return map.put(key, value);
} finally {
readLock.unlock();
}
}
@Override
public void putAll(@NotNull Map<? extends K, ? extends V> m) {
try{
// Take a read-lock so they know when I'm finished.
readLock.lock();
map.putAll(m);
} finally {
readLock.unlock();
}
}
@Nullable
@Override
public V putIfAbsent(K key, V value) {
try{
// Take a read-lock so they know when I'm finished.
readLock.lock();
return map.putIfAbsent(key, value);
} finally {
readLock.unlock();
}
}
// All other methods are simply delegated - but you may wish to disallow some of them (like `entrySet` which would expose the map to modification without locks).
@Override
public Set<Entry<K, V>> entrySet() {
return map.entrySet();
}
@Override
public boolean equals(Object o) {
return map.equals(o);
}
@Override
public int hashCode() {
return map.hashCode();
}
// ... The rest of the delegators (left to the student)
添加回答
舉報