Есть ли у меня лучший вариант, чем CopyOnWriteArrayList и Collections.synchronizedList? - PullRequest
0 голосов
/ 06 мая 2020

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

Простая замена моего ArrayList на CopyOnWriteArrayList работает, но я боюсь потери производительности (мой список содержит координаты GPS, обновляемые каждые 2 секунды, и я бы хотел, чтобы он работал как можно дольше).

Использование Collections.synchronizedList также работает, если я оборачиваю каждый доступ к получателю списка в synchronized() {} block, что означает, что мне нужно go через весь код приложения для проверки.

Я пытался:

  • объявить мой получатель как synchronized
  • обернуть return myList; моего геттера в синхронизированный блок

Но оба приводят к ConcurrentModificationException при чтении списка во время его записи.

Есть ли лучший вариант, чем CopyOnWriteArrayList или добавление блоков synchronized() {} повсюду?

Если это важно, это приложение Android.

РЕДАКТИРОВАТЬ: вот некоторый код, иллюстрирующий мои две попытки с использованием геттера:

ArrayList<MyObject> mList = Collections.synchronizedList(new ArrayList<>());

public ArrayList<MyObject> getList() {
    synchronized(this) {
        return mList;
    }
}

public synchronized ArrayList<MyObject> getList() {
    return mList;
}

РЕДАКТИРОВАТЬ 2: вот дополнительная информация о варианте использования, следуя @Martin Marconci ni комментарии:

  • приложение может загружать файлы KML (файлы, содержащие такие функции, как маркеры, линии и многоугольники) на карту Google
  • У меня есть класс Map, в котором ArrayLists содержит ссылки на каждый загруженная функция. У этого класса есть метод load (Feature f), который загружает данную функцию на карту Google и сохраняет ее в подходящий список ArrayList (либо маркеры, либо список линий, либо список многоугольников).
  • У меня есть класс KmlFileLoader, анализирующий KML files
  • У меня есть класс KmlFile, в котором ArrayLists содержат ссылки на все функции файла (которые могут быть загружены на карту или нет). У этого класса есть loadOnMap (карта карты), который будет вызывать map.load (Feature f) для каждой функции. Здесь происходит ConcurrentModification: если я обращаюсь к функциям карты во время загрузки в нее файла.

На самом деле, в моем коде не так много мест, где я повторяю списки за пределами Класс карты, поэтому решить проблему для этого проекта с помощью синхронизированных блоков намного проще, чем я думал изначально. Внутри класса карты я уже синхронизировал все методы доступа к спискам, поэтому здесь нет никаких проблем (мне даже не нужно использовать Collections.synchronizedList, так как я синхронизируюсь с объектом Map).

Но мне все еще интересно знать, есть ли лучший вариант, чем использование CopyOnWriteArrayList и перенос моих геттеров в синхронизированные блоки. Думаю, нет.

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