Я столкнулся с проблемой в моей программе, когда несколько потоков обращаются к одному и тому же серверу через RMI. Сервер содержит список в качестве кеша и выполняет некоторые дорогостоящие вычисления, иногда изменяя этот список. После завершения вычислений список будет сериализован и отправлен клиенту.
Первая проблема: если список изменяется во время сериализации (например, другим клиентом, запрашивающим некоторые данные), (вероятно) выбрасывается ConcurrentModificationException
, что приводит к EOFException
для вызова RMI/десериализации на клиенте -боковая сторона.
Поэтому мне нужна какая-то структура списка, которая стабильна для сериализации, но, возможно, изменяется другим потоком.
Решения, которые мы пробовали:
- обычный ArrayList/Set - не работает из-за параллелизма
- глубокое копирование всей структуры перед каждой сериализацией - слишком дорого
CopyOnWriteArrayList
- тоже дорого, так как копирует список и
раскрывая Вторую проблему: нам нужно иметь возможность атомарно заменить любой элемент в списке, который в настоящее время не является потокобезопасным (сначала удалить, затем добавить (что еще дороже)) или выполнимо только с помощью блокирует список и, следовательно, выполняет только разные потоки последовательно.
Поэтому мой вопрос таков:
Знаете ли вы о
Collection
реализации, которая позволяет намserialize
сделать Коллекцию потокобезопасной, в то время как другие потоки модифицируют ееand
, которая содержит некоторые элементыatomically replacing
?Бонусом было бы, если бы список
not
должен был бытьcopied
перед сериализацией! Создание моментального снимка для каждой сериализации было бы нормально, но все равно :/
Иллюстрация проблемы (C=вычислить, A=добавить в список, R=удалить из списка, S=сериализовать)
Thread1 Thread2
C
A
A C
C A
S C
S R <---- Remove and add have to be performed without Thread1 serializing
S A <---- anything in between (atomically) - and it has to be done without
S S blocking other threads computations and serializations for long
S and not third thread must be allowed to start serializing in this
S in-between state
S
remove(index)
) или используете поиск и удаление (например,remove(Object)
)? - person Tagir Valeev   schedule 28.09.2015replaceWithObj(Object, Object)
, не по индексу, а путем проверки каждого объекта на равенство. И в настоящее время, позвонивremove(Object)
, а затемadd(slightlyDifferentObj)
- person luk2302   schedule 28.09.2015