ArrayList — это несинхронизированная коллекция, и ее не следует использовать в параллельной среде без явной синхронизации. Для синхронизации ArrayList мы можем использовать два метода, предоставляемых JDK.
- Метод Collections.synchronizedList(), который возвращает синхронизированный список, поддерживаемый указанным списком.
- Класс CopyOnWriteArrayList, который является потокобезопасным вариантом ArrayList.
1. Использование Collections.synchronizedList()
synchronizedList() возвращает синхронизированный и потокобезопасный список, поддерживаемый указанным списком.
List syncList = Collections.synchronizedList(arraylist);
- Рекомендуется вручную синхронизировать возвращаемый список при его прохождении через Iterator, Spliterator или Stream, в противном случае это может привести к недетерминированному поведению.
- Для добавления или удаления элементов из этого синхронизированного массива не требуется явной синхронизации.
List<String> namesList = Collections.synchronizedList(new ArrayList<String>());//List methods are synchronizednamesList.add("Alex");namesList.add("Brian");//Use explicit synchronization while iteratingsynchronized(namesList){Iterator<String> iterator = namesList.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}}
Вывод программы.
AlexBrian
2. Использование CopyOnWriteArrayList
CopyOnWriteArrayList — это потокобезопасный вариант ArrayList, в котором все мутационные операции(add, set и т. д.) реализуются путем создания новой копии базового массива. Этот класс очень полезен, когда мы не можем или не хотим синхронизировать обходы arraylist. Он является частью потокобезопасных коллекций Java.
Класс CopyOnWriteArrayList использует метод итератора в стиле «снимка». Он использует ссылку на состояние резервного массива в момент создания итератора. Этот резервный массив никогда не изменяется в течение срока службы итератора.
- Итератор не будет отражать добавления, удаления или изменения в списке с момента его создания.
- Операции изменения элементов самих итераторов(удаление, установка и добавление) не поддерживаются.
CopyOnWriteArrayList<String> namesList = new CopyOnWriteArrayList<String>();//List methods are synchronizednamesList.add("Alex");namesList.add("Brian");//No explicit synchronization is needed during iterationIterator<String> iterator = namesList.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}
Вывод программы.
AlexBrian
Подробнее: Документация по ArrayList Java