CopyOnWriteArrayList
Операции add, set, remove в данной коллекции приводят к созданию новой копии внутреннего массива. Это гарантирует то, что мы не словим ConcurrentModificationException.
Не забывай только о том, что при копировании массива копируются только ссылки на объекты, в том числе доступ к полям элементов не thread-safe. Такие коллекции лучше использовать в случаях с минимальным количеством write операций.

CopyOnWriteArrayList<E> — потокобезопасный аналог ArrayList, реализованный на основе CopyOnWrite алгоритмов. Дополнительные методы и конструктор описаны внизу:
CopyOnWriteArrayList(E[] toCopyIn) | Конструктор, принимающий на вход массив. |
int indexOf(E e, int index) | Возвращает индекс первого найденного элемента, начиная поиск с заданного индекса. |
int lastIndexOf(E e, int index) | Возвращает индекс первого найденного элемента при обратном поиске, начиная с заданного индекса. |
boolean addIfAbsent(E e) | Добавить элемент, если его нет в коллекции. Для сравнения элементов используется метод equals. |
int addAllAbsent(Collection<? extends E> c) | Добавить элементы, если они отсутствуют в коллекции. Возвращает количество добавленных элементов. |
Интерфейс ConcurrentMap
Улучшенные реализации HashMap и TreeMap с поддержкой многопоточности и масштабируемости.

ConcurrentMap<K, V> — интерфейс, расширяющий Map дополнительными атомарными операциями.
V putIfAbsent(K key, V value) | Добавляет новую пару key-value только в том случае, если ключа нет в коллекции. Возвращает предыдущее значение для заданного ключа. |
boolean remove(Object key, Object value) | Удаляет key-value пару только если заданному ключу соответствует заданное значение в Map. Возвращает true, если элемент был успешно удален. |
boolean replace(K key, V oldValue, V newValue) | Заменяет старое значение на новое по ключу только если старое значение соответствует заданному значению в Map. Возвращает true, если значение было заменено на новое. |
V replace(K key, V value) | Заменяет старое значение на новое по ключу только если ключ ассоциирован с любым значением. Возвращает предыдущее значение для заданного ключа. |
ConcurrentHashMap<K, V> — здесь данные представлены в виде сегментов, которые разбиты по hash'ам ключей. По итогу, если вам нужен доступ, то лочится сегмент, а не объект. Итераторы не кидают ConcurrentModificationException и представляют данные на определенный отрезок времени.
Реализации ConcurrentHashMap
ConcurrentHashMap<K, V> — тут данные представлены в виде сегментов, разбитых по hash'ам ключей. В результате, для доступа к данным лочится по сегментам, а не по одному объекту. В дополнение итераторы представляют данные на определенный срез времени и не кидают ConcurrentModificationException.
ConcurrentNavigableMap<K,V> — расширяет интерфейс NavigableMap и возвращает ConcurrentNavigableMap. Все итераторы безопасны для использования и не кидают ConcurrentModificationException.
ConcurrentSkipListMap<K, V> — является аналогом TreeMap для многопоточности. Данные сортируются по ключу и гарантируется усредненная производительность log(N) для containsKey, get, put, remove и других похожих операций.
ConcurrentSkipListSet<E> — имплементация интерфейса Set на основе ConcurrentSkipListMap.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ