in java 8+ ConcurrentHashMap as a compute() function that allows you to do atomic read-modify-write operation on a single key, so you could do something like:
map.compute(key, () -> {
//call func2 to compute new value and return it
});
if, however, you want atomic read-modify-write for the entire set of keys (so 1st you iterate over your set of keys to compute result and then change all those keys using that pre-computed result) then there's no facility in ConcurrentHashMap to provide that locking.
you could, however, use guava's Striped lock, like so:
Striped<Lock> arrayOfLocks = Striped.lock(20);
// ...later on...
K = subset(keySet, m);
Iterable<Lock> toObtain = arrayOfLocks.bulkGet(K);
for (Lock l : toObtain) { lock it }
try {
//do your modifications - your holding the stripe locks for all the keys
} finally {
for (Lock l : toObtain) { unlock it }
}
lock striping is the concept of assigning locks to different "area"s of a data structure - here its done by the hashCode of your keys.
you need to pick the size of the lock array very carefully to balance between too-few stripes (where you'll lock the whole map and do it slower than a single global lock) and too-many stripes (where you'll be grabbing a lot of locks, depending onthe size of K).
Striped takes care of returning the locks in the same order for the same set of keys to lock so that you avoid the dining philosophers problem.