0

I have a Java HashMap that is normally read and modified by a single thread. When the thread writes to this map via put, I have the following bit of code that validates some preconditions:

void put(Set<Stuff> toAdd, long id) {

/// ....

toAdd.forEach(stuff -> {
   long prevId = map.getOrDefault(stuff, NO_EXIST)
   Preconditions.checkState(prevId < id);
})

/// Update map here
toAdd.forEach(stuff -> {
    map.put(stuff, id);   
})

/// ...

}

Even though this is a regular HashMap, I was wondering if it was safe to use a parallelStream here as follows to help speed things up:

void put(Set<Stuff> toAdd, long id) {

/// ....

toAdd.parallelStream().forEach(stuff -> {
   long prevId = map.getOrDefault(stuff, NO_EXIST)
   Preconditions.checkState(prevId < id);
})

/// Update map here
toAdd.forEach(stuff -> {
    map.put(stuff, id);   
})

/// ...

}

I have read in previous posts that multiple concurrent readers should not be an issue, and in this case, the map is only accessible to the calling (single) thread for modifications, and this will not occur until after the preconditions are validated. Likewise, if this thread wants to do another put, no other thread will be performing any operations on that map. Hence, outside this parallel stream (which only contains reads), there are no concurrent operations ever. Are there any correctness implications or potential visibility issues for doing this?

Similar question: Java hashmap readonly thread safety

Nizbel99
  • 123
  • 6
  • Do you mean to `stream()` over `toAdd` in your second code sample? – daniu Aug 30 '22 at 13:00
  • Yes sorry for the mistake in my original post. I have updated it. – Nizbel99 Aug 30 '22 at 13:03
  • 2
    This seems to be a safe operation but at the same time, it seems to be of no benefit. The operation itself is so trivial that you’d need a humongous set to compensate the initial overhead of initiating a parallel operation. But when you use a Stream, you should use it in the intended way, e.g. `Preconditions .checkState(toAdd.stream().allMatch(stuff -> map.getOrDefault(stuff, NO_EXIST) – Holger Sep 21 '22 at 09:29

0 Answers0