I am trying to populate a cache which hold the key/value with ConcurrentHashMap.
I am assuming using a CopyOnWriteArrayList
takes care of concurrency and I have that as my value for my key, but I am missing something in the below code and it is overriding its values when multiple threads are executing.
if (testMap.get(id) == null) {
CopyOnWriteArrayList<String> copyArr = new CopyOnWriteArrayList<String>();
copyArr.add("Add Value");
testMap().putIfAbsent(id, copyArr);
} else {
testMap.put(id,testMap.get().add("Append Value"));
}
How do I protect the code which creates the CopyOnWriteArrayList
from multiple threads.
Here is the revised version of code as per the suggestions below.
CopyOnWriteArrayList<Subscriber> subscriberArr = CacheUtils.getSubscriberMap().get(syncDet.getCardNumber());
if (subscriberArr == null) {
subscriberArr = new CopyOnWriteArrayList<Subscriber>();
CopyOnWriteArrayList<Subscriber> refArr =
cacheUtils.getSubscriberMap().putIfAbsent(syncDet.getCardNumber(), subscriberArr);
if (refArr != null) {
subscriberArr = refArr;
}
}
subscriberArr.add(syncDet.getSubScriber());
On iterating the subscriber map i dont see a value object. size is 0 .
You need to first retrieve the appropriate list then populate it. Something like:
List<String> copyArr = testMap.get(id);
if (copyArr == null) {
copyArr = new CopyOnWriteArrayList<String>();
List<String> inMap = testMap.putIfAbsent(id, copyArr);
if (inMap != null) copyArr = inMap; // already in map
}
copyArr.add("Add Value");
That way you only put a new list in the map if there wasn't already one and you add your item to whatever list has made it to the map.