Лучшая реализация NullPointerException, когда два потока иногда обращаются к одному и тому же списку, а другой очищает еJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Лучшая реализация NullPointerException, когда два потока иногда обращаются к одному и тому же списку, а другой очищает е

Сообщение Anonymous »

Проблема проста, но я хочу решить ее, не замедляя общую обработку приложения или не перестраивая свой код.
Возможно, ответ уже был в другом постере.
У меня есть переменная типа List внутри объекта Window.
К этому списку обращаются несколько раз через базовый метод получения:

Код: Выделить всё

public List getFiles() {
return files;
}
С одним и тем же списком работают два разных потока:
Поток A (архивирование) → выполняет итерацию по списку для архивирования определенных файлов.
Поток B (сортировка) → полностью очищает список, а затем повторно заполняет его в новом порядке (в соответствии с вызванной внешней ссылкой).
Вот упрощенная версия задействованного кода:
Поток A :

Код: Выделить всё

  public WindowFile retrieveWindowFile(AbstractWindow pWindow, String pFileName) {
WindowFile lWindowFile = null;
for (WindowFile lFile : pWindow.getFiles()) {
if (lFile.getFileName().equals(pFileName)) {
lWindowFile = lFile;
break;
}
}
return lWindowFile;
}
Поток B

Код: Выделить всё

pWindow.getFiles().clear();
pWindow.getFiles().addAll(lMap.values());
Поскольку оба потока работают параллельно, иногда поток архивирования читает список, в то время как другой его очищает.
Это приводит к редкому, но критическому исключению NullPointerException во время выполнения, и мы теряем архив.
🔍 Что я рассмотрел
Я ищу лучший способ предотвратить эту проблему, не добавляя слишком много синхронизации накладные расходы.
Вот возможные подходы, которые я определил на данный момент:
  • Синхронизировать метод получения.
    Просто реализовать, но может часто блокироваться, если список часто читается.
  • Синхронизировать непосредственно в списке (например, Synchronized(files) { ... }) во время операций чтения/записи.
    Работает хорошо, пока ссылка на файлы никогда не переназначается.
  • Создайте копию (снимок) списка перед его изменением или перебором.
    Избегает блокировки других потоков, но немного увеличивает использование памяти.
  • Используйте параллельную структуру, такую ​​как CopyOnWriteArrayList или ReadWriteLock.
    Может быть излишним, поскольку список часто перестроен с нуля.
Проблема возникает очень редко — я просто хочу сделать его потокобезопасным, не влияя на общую производительность.
Какой подход будет лучшим в этом конкретном случае?
Рекомендуете ли вы просто синхронизировать список или лучше каждый раз делать снимок?
Есть ли более чистое или эффективное решение без рефакторинг всей архитектуры?
Заранее спасибо

Подробнее здесь: https://stackoverflow.com/questions/797 ... ss-and-the
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»