Я исследую ошибку, которая, я уверен, связана со временем из-за ее использования в нескольких потоках.Я думаю, что нашел код, который потенциально мог быть проблемой, но мне было интересно, смогу ли я получить подтверждение того, что, по моему мнению, происходит.
Рассмотрим следующий фрагмент кода:
public MyClass {
private Map<String, Map<String, String>> managedMap = Collections.synchronizedMap(new HashMap<>);
public purgeOldData() {
Map<String, Map<String, String>> cpyManagedMap = Collections.synchronizedMap(new HashMap<>(managedMap));
cpyManagedMap.forEach((primaryKey, pkMap) -> {
Map<String, String> cpyPkMap = new HashMap<>(pkMap);
cpyPkMap.forEach((secondKey, value) -> {
checkToPurge(primaryKey, pkMap, secondKey, value);
});
});
}
private checkToPurge(String primaryKey, Map pkMap, String secondKey, String value) {
synchronized (managedMap) {
if (someMethodThatReturnsBoolean()) {
pkMap.remove(secondKey);
if (pkMap.isEmpty()) {
managedMap.remove(primaryKey);
}
}
}
}
}
ИтакmanagedMap - это член класса, который используется по всему классу в синхронизированных блоках по мере необходимости.В purgeOldData () создается копия managedMap и копия синхронизируется.Таким образом, cpyManagedMap представляет собой снимок управляемого файла в определенное время.
После того, как копия сделана, есть пара циклов, чтобы наконец получить данные, которые мы хотим проверить.Эти данные отправляются в метод checkToPurge ().Внутри этого метода весь этот метод синхронизируется с исходной управляемой картой.
Наконец-то мы добрались до моих вопросов:
Поскольку cpyManagedMap - это моментальный снимок, не так ли?Возможно, что ManagerMap обновляется во время между копией и блоком синхронизации в checkToPurge ()?Это означает, что копия используется, чтобы определить, следует ли удалить что-либо из исходной управляемой карты, которая могла быть обновлена?
Действительно ли в этом случае необходимо синхронизировать cpyManagedMap?
Есть какие-нибудь предложения относительно того, как исправить код, если действительно мое опасение по поводу возможного обновления mamagedMap верно?Должен ли я просто синхронизировать весь код в purgeOldData с managedMap?
Спасибо!