The code snippet below updates a not-thread-safe map (itemsById is not thread safe) from a parallel stream's forEach block.
// Update stuff in `itemsById` by iterating over all stuff in newItemsById: newItemsById.entrySet() .parallelStream() .unordered() .filter(...) .forEach(entry -> { itemsById.put(entry.getKey(), entry.getValue()); <-- look }); To me, this looks like not-thread-safe, because the parallel stream will call the forEach block in many threads at the same time, and thus call itemsById.put(..) in many threads at the same time, and itemsById isn't thread safe. (However, with a ConcurrentMap the code would be safe I think)
I wrote to a colleague: "Please note that the map might allocate new memory when you insert new data. That's likely not thread safe, since the collection is not thread safe. -- Whether or not writing to different keys from many threads, is thread safe, is implementation dependent, I would think. It's nothing I would choose to rely on."
He however says that the above code is thread safe. -- Is it?
((Please note: I don't think this question is too localized. Actually now with Java 8 I think fairly many people will do something like: parallelStream()...foreach(...) and then it might be good know about thread safety issues, for many people))
Mapimplementations, you don’t need memory allocations to fail in case of concurrent updates, simple re-linking of object structures can cause arbitrary errors. Even actions as simple as incrementing theintholding the map’s size are not atomic and can cause loss of updates when performed concurrently, thus produce an inconsistent data structure.