Потокобезопасный HashMap объектов с вложенным ArrayList - PullRequest
1 голос
/ 25 октября 2019

У меня есть HashMap объектов с вложенными списками ArrayLists, доступ к которым осуществляется несколькими потоками.

Мне интересно, достаточно ли объявления его как синхронизированного HashMap, чтобы сделать его поточно-ориентированным.

public class ExampleRepository {

    private static Map<String, Example> examples = Collections.synchronizedMap(new HashMap<>());

    public static void addExample(Example example) {
        examples.put(example.getKey(), example);
    }

    public static Example getExample(String key) {
        return examples.get(key);
    }

}
public class Example {

    private String key;
    // More attributes
    private List<AnotherObject> anotherObjectList = new ArrayList<>();

    // Constructor

    public List<AnotherObject> getAnotherObjectList() {
        return anotherObjectList;
    }

    // More getters & Setters

}
public class Doer {

    // This function runs in an ExecutorService with many threads
    public static one(String key) {
        Example example = ExampleRepository.getExample(key);
        if (example != null) {
            // Do stuff
            example = new Example(values);
            AnotherObject anotherObject = new AnotherObject(values);
            example.getAnotherObjectList().add(anotherObject);
            ExampleRepository.addExample(example);
        }
        two(example);
    }

    private static two(Example example) {
        // Do stuff
        AnotherObject anotherObject = new AnotherObject(values);
        trim(example.getAnotherObjectList(), time);
        example.getAnotherObjectList().add(anotherObject);
    }

     private static void trim(List<AnotherObject> anotherObjectList, int time) {
        short counter = 0;
        for (AnotherObject anotherObject : anotherObjectList) {
            if (anotherObject.getTime() < time - ONE_HOUR) {
                counter++;
            } else {
                break;
            }
        }
        if (counter > 0) {
            anotherObjectList.subList(0, counter).clear();
        }
    }

}

Я предполагаю, что вопрос заключается в добавлении объектов-примеров кHashMap поток безопасно? Кроме того, удаление и добавление объектов AnotherObject в многопоточный список безопасным для потоков или я должен объявить его как синхронизированный ArrayList?

Я был бы очень признателен за любые идеи. Большое спасибо!

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

Еще раз спасибо!

Ответы [ 2 ]

1 голос
/ 25 октября 2019

Вы должны четко понимать, что вы подразумеваете под "потокобезопасным".

Я полагаю, что вопрос заключается в добавлении объектов примеров в потокобезопасный HashMap?

Синхронизация карты гарантирует, что структурные изменения, сделанные вами на карте, будут видны всем потокам.

Кроме того, удаление и добавление объектов AnotherObjet во вложенный список является поточно-безопасным или долженобъявили его как синхронизированный ArrayList?

Нет: вам потребуется внешняя синхронизация доступа к спискам, если вы хотите, чтобы структурные изменения в списках были видны во всех потоках.

Это можетозначает использование synchronizedList, но вы можете «вручную» выполнить синхронизацию в списке или даже на карте (или одним из ряда других способов создания гарантий «до и после»).

0 голосов
/ 25 октября 2019

Я полагаю, вопрос заключается в добавлении объектов примеров в потокобезопасный поток HashMap?

-> Да, размещение объекта примера на карте является потокобезопасным.

Кроме того, удаление и добавление объектов AnotherObjet в многопоточный список является поточно-безопасным или я должен объявить его как синхронизированный ArrayList?

-> Удаление объектов из списка не гарантирует, что оно будет поточно-безопасный.

Любая операция на карте будет поточно-ориентированной, поскольку вы использовали Синхронизированную карту. ArrayList в объекте Example будет по-прежнему небезопасен для потока.

Потокобезопасность в коллекции / карте не означает, что он сделает API любого / каждого объекта, который он содержит, потокобезопасным.

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