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 String
codes to inner singleton maps, and each inner map maps exactly one code to a Model
. The Model
s 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 the code
property of the corresponding Model
.
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 the Model
objects as atomic groups, without blocking concurrent modification of different Model
objects.
Multiple threads will try to update values of same mainCode, does below cause trouble?
Each entire invocation of ConcurrentHashMap.compute()
is performed atomically, so multiple threads invoking securities.compute()
via your updateModel()
method, whether for the same or for different keys, will not interfere with each other with respect to the securities
map itself.
Similarly, multiple threads concurrently invoking modifyValue()
with the same first argument will not interfere with each other with respect to that map. The Model
-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 Model
objects 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:
Model
objects immutable, and remove the inner maps (the outer map will map codes directly to Model
s). Instead of updating existing Model
objects, replace them with new ones having the desired properties.OR
Model
objects, 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).