I have a parallel stream in which I'm using a Map to mutate the elements.
Map<Long, List<MyItem>> hashmap = foo.getMap();
itemStream.parallel()
.filter(Objects::nonNull)
.forEach(item -> setProperties(hashmap, item));
The method 'setProperties()' takes the map and item, and performs a get using item and then sets some attributes of the item.
What I want is for the getting/property setting to be done atomically. So that two threads can't perform a get on the same key and have property updates be interleaved.
private void setProperties(Map<Long, List<Item>> map, Item item) {
long id = item.getID();
List<Object1> items = map.get(id);
for (Object1 ob : items) {
ob.setId(item.getFloorId());
ob.setPath(item.getPath());
ob.setTypeName(item.getTypeName());
}
}
Also a bit concerned about the latency hit and whether this sort of parallelization will really have a benefit vs the existing single threaded approach.
Synchnorising the Map or the get from it has no benefit, because the map is not being altered so there’s no race condition.
You need to synchronise the updates so they happen all-at-once:
for (Object1 ob : items) {
synchronized (ob) {
ob.setId(item.getFloorId());
ob.setPath(item.getPath());
ob.setTypeName(item.getTypeName());
}
}
This will have very little impact on performance, because these days synchronising introduces very little overhead and you will only block if the same Item is being operated on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With