ArrayList is non-synchronized collection and should not be used in a concurrent environment without explicit synchronization. To synchronize an ArrayList, we can use two JDK-provided methods.
- Collections.synchronizedList() method that returns a synchronized list backed by the specified list.
- CopyOnWriteArrayList class that is a thread-safe variant of ArrayList.
1. Using Collections.synchronizedList()
The synchronizedList() returns a synchronized and thread-safe list backed by the specified list.
List syncList = Collections.synchronizedList(arraylist);
- It is recommended that we should manually synchronize the returned list when traversing it via
Iterator
,Spliterator
orStream
else it may result in non-deterministic behavior. - No explicit synchronization is needed to add, or remove elements from this synchronized arraylist.
List<String> namesList = Collections.synchronizedList(new ArrayList<String>());
//List methods are synchronized
namesList.add("Alex");
namesList.add("Brian");
//Use explicit synchronization while iterating
synchronized(namesList)
{
Iterator<String> iterator = namesList.iterator();
while (iterator.hasNext())
{
System.out.println(iterator.next());
}
}
Program output.
Alex
Brian
2. Using CopyOnWriteArrayList
The CopyOnWriteArrayList is a thread-safe variant of ArrayList in which all mutative operations (add, set, and so on) are implemented by making a fresh copy of the underlying array. This class is very useful when we cannot or do not want to synchronize the traversals of the arraylist. It is part of thread-safe Java collections.
The CopyOnWriteArrayList class uses “snapshot” style iterator method. It uses a reference to the state of the backing array at the point that the iterator was created. This backing array never changes during the lifetime of the iterator.
- The iterator will not reflect additions, removals, or changes to the list since the iterator was created.
- Element-changing operations on iterators themselves (remove, set, and add) are not supported.
CopyOnWriteArrayList<String> namesList = new CopyOnWriteArrayList<String>();
//List methods are synchronized
namesList.add("Alex");
namesList.add("Brian");
//No explicit synchronization is needed during iteration
Iterator<String> iterator = namesList.iterator();
while (iterator.hasNext())
{
System.out.println(iterator.next());
}
Program output.
Alex
Brian
Happy Learning !!
Read More: ArrayList Java Docs