Лично мое мнение по поводу любых коллекций и многопоточности.
используйте блокировки, причем использовать их нужно там где существует возможность вхождения нескольких потоков в чтение и запись.
А использование Concurrent на мой взгяд - костыль. Ибо при записи создается копия коллекции... что при определенных обстоятельствах может повести за собой баги или даже дюп.
Код:
Чтение
locker.enterReadLock();
Тут операции чтения из коллекции
locker.exitReadLock();
Запись
locker.enterWriteLock();
Тут операции записи коллекции (добавление\удаление)
locker.exitWriteLock();
Не знаю как в java но в c# реализация локера следующая
Код:
using System.Threading;
namespace Utils.Locks
{
public sealed class ReadWriteLockerPro
{
private ManualResetEvent writeLock = new ManualResetEvent(true);
private ManualResetEvent readLock = new ManualResetEvent(true);
private int readers = 0;
public void enterWriteLock()
{
readLock.WaitOne();
writeLock.Reset();
}
public void exitWriteLock()
{
writeLock.Set();
}
public void enterReadLock()
{
writeLock.WaitOne();
readLock.Reset();
Interlocked.Increment(ref readers);
}
public void exitReadLock()
{
Interlocked.Decrement(ref readers);
if (readers == 0)
readLock.Set();
}
}
}
Суть - Читатели могут(параллельно) читать до тех пор пока в очередь не зайдет писатель. Если в момент вхождения писателя не все читатели закончили чтение писатель ждет пока читатели закончат чтение, Но новые читатели уже не могут читать. Как читатели закончили - писатель начинает писать. Если другой писатель (Практически исключено. Если так происходит - значит ваша архитектура - х**ня.) входит, то он ждет пока предыдущий писатель закончит писать. Как только писатели закончили писанину - разрешаем читателям, которые были в очереди - читать дальше.
PS удалять элементы коллекции в цикле итерации по самой же коллекции - нельзя. Выход - те элементы которые нужно удалить в цикле помещаем в коллекцию удаления. Прим ArrayList<item> deletedList;
и потом уже после цикла главной коллекции - добавляем цикл удаления если deletedList.count > 0. и в нем уже удаляем элементы из главной коллекции а после deletedList.clear();