Действительно ли этот синхронизированный код делает то, что хотел автор? - PullRequest
0 голосов
/ 28 сентября 2018

Я исследую ошибку, которая, я уверен, связана со временем из-за ее использования в нескольких потоках.Я думаю, что нашел код, который потенциально мог быть проблемой, но мне было интересно, смогу ли я получить подтверждение того, что, по моему мнению, происходит.

Рассмотрим следующий фрагмент кода:

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 ().Внутри этого метода весь этот метод синхронизируется с исходной управляемой картой.

Наконец-то мы добрались до моих вопросов:

  1. Поскольку cpyManagedMap - это моментальный снимок, не так ли?Возможно, что ManagerMap обновляется во время между копией и блоком синхронизации в checkToPurge ()?Это означает, что копия используется, чтобы определить, следует ли удалить что-либо из исходной управляемой карты, которая могла быть обновлена?

  2. Действительно ли в этом случае необходимо синхронизировать cpyManagedMap?

  3. Есть какие-нибудь предложения относительно того, как исправить код, если действительно мое опасение по поводу возможного обновления mamagedMap верно?Должен ли я просто синхронизировать весь код в purgeOldData с managedMap?

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...