Multiple threads will try to update values of same mainCode, does below cause trouble? Also another job will consistently read values of securities and apply operations if values match.
public class MyObj {
private static ConcurrentHashMap<String, ConcurrentHashMap<String, Model>> securities = new ConcurrentHashMap<>();
private static void updateModel(String mainCode, String code, BigDecimal valueA, BigDecimal valueB) {
securities.compute(mainCode, (k, v) -> {
modifyValue(v, valueA, valueB, code);
return v;
});
}
private static void modifyValue(ConcurrentHashMap<String, Model> v, BigDecimal valueA, BigDecimal ValueB, String code) {
v.compute(code, (k, val) -> {
val.setCode(code);
val.setValueA(valueA);
val.setValueB(ValueB);
return val;
});
}
}
Interpreting your data structure based on the code you're using to access it, you have an outer map from
Stringcodes to inner singleton maps, and each inner map maps exactly one code to aModel. TheModels have multiple distinct properties that are to be updated, as a group, from time to time. Each key of the outer map is the same as the single key of the corresponding inner map. Each key of each inner map is the same as thecodeproperty of the correspondingModel.I guess, then, the idea for the inner maps, which otherwise seem redundant, is to use their
ConcurrentHashMap.compute()methods to perform modifications of multiple properties of theModelobjects as atomic groups, without blocking concurrent modification of differentModelobjects.Each entire invocation of
ConcurrentHashMap.compute()is performed atomically, so multiple threads invokingsecurities.compute()via yourupdateModel()method, whether for the same or for different keys, will not interfere with each other with respect to thesecuritiesmap itself.Similarly, multiple threads concurrently invoking
modifyValue()with the same first argument will not interfere with each other with respect to that map. TheModel-property modifications will be performed as an atomic group with respect to other operations on the map.But that's not sufficient. If those properties of your
Modelobjects are accessed by any other path (and surely they are at least read at some point), then that produces data races. At minimum, those reads can observe inconsistent combinations of property values.It might be possible to build sufficient additional infrastructure around this nested-map idea to serve all your needs without data races, but this cure is probably worse than the disease. I see two potential approaches that are superior:
Modelobjects immutable, and remove the inner maps (the outer map will map codes directly toModels). Instead of updating existingModelobjects, replace them with new ones having the desired properties.OR
Modelobjects, and remove the inner maps.If (1) is viable for you with respect to the other requirements of your application then that's what I would recommend. If not, then probably there is no alternative better than (2).