I need concurrent HashMap of List as value with following behavior:
- count of read/write ops approximately equals
- support add/remove values in lists
- thread safe iterations over lists
After some research I implemented ConcurrentMapOfList, but I'm not sure in his correctness.
public class ConcurrentMapOfList<Key, ListValue> {
private final ConcurrentMap<Key, ConcurrentList<ListValue>> values
= new ConcurrentHashMap<Key, ConcurrentList<ListValue>>();
public void add(Key key, Value value) {
List<Value> list = values.get(key);
if (list == null) {
final ConcurrentList<Value> newList = new ConcurrentList<Value>();
final ConcurrentList<Value> oldList = values.putIfAbsent(key, newList);
if (oldList == null) {
list = newList;
} else {
list = oldList;
}
}
list.add(value);
}
public List<ListValue> remove(Key key) {
return values.remove(key);
}
public boolean remove(Key key, ListValue value) {
final List<ListValue> list = values.get(key);
if (list == null) {
return false;
}
return list.remove(value);
}
public List<ListValue> obtainListCopy(Key key) {
final ConcurrentList<ListValue> list = values.get(key);
if (list == null) {
return Collections.emptyList();
}
return list.clone();
}
public void removeAll() {
values.clear();
}
private class ConcurrentList<V> extends ArrayList<V> {
final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
final Lock readLock = lock.readLock();
final Lock writeLock = lock.writeLock();
@Override
public boolean add(V v) {
writeLock.lock();
try {
return super.add(v);
}finally {
writeLock.unlock();
}
}
@Override
public V remove(int index) {
writeLock.lock();
try {
return super.remove(index);
}finally {
writeLock.unlock();
}
}
@Override
public ConcurrentList<V> clone() {
readLock.lock();
try {
return (ConcurrentList<V>)super.clone();
}finally {
readLock.unlock();
}
}
}
}
synchronizedMap
fromCollections
? It seems to me that this would be the easier and safer solution. From a quick look, your implementation will e.g. fail if you add element and copy it in parallel. – tb- Apr 9 at 17:41