java - How to populate concurrenthashmap from multiple threads? -
i have concurrenthashmap populating multiple threads.
private static map<datacode, long> errormap = new concurrenthashmap<datacode, long>(); public static void adderror(datacode error) { if (errormap.keyset().contains(error)) { errormap.put(error, errormap.get(error) + 1); } else { errormap.put(error, 1l); } }
my above adderror
method called multiple threads populates errormap
. not sure whether thread safe? there wrong doing here?
any explanation of why can skip updates me understand better.
whether safe depends on mean. won't throw exceptions or corrupt map, can skip updates. consider:
- thread1: errormap.get(error) returns 1
- thread2: errormap.get(error) returns 1
- thread1: errormap.put(error, 1+1);
- thread2: errormap.put(error, 1+1);
a similar race exists around keyset().contains(error)
operation. fix you'll need use atomic operations update map.
on java 8, easy:
errormap.compute(error, oldvalue -> oldvalue == null ? 1l : oldvalue + 1l);
on older versions of java need use compare-and-update loop:
long prevvalue; boolean done; { prevvalue = errormap.get(error); if (prevvalue == null) { done = errormap.putifabsent(error, 1l); } else { done = errormap.replace(error, prevvalue, newvalue); } } while (!done);
with code, if 2 threads race 1 may end retrying update, they'll right value in end.
alternately, can use guava's atomiclongmap thread-safety magic , gets higher performance (by avoiding boxing operations, among other things):
erroratomiclongmap.incrementandget(error);
Comments
Post a Comment