EN
Java - iterate over synchronized ArrayList - Collections.synchronizedList(new ArrayList<>())
7
points
In this article, we would like to show you how to iterate over synchronized ArrayList in thread safe way in java.
When iterating the iterator must be synchronized by programmer.
Quick solution:
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
synchronized (syncList) {
// iterate over list
}
Why do we need to synchronize iteration of list?
- When we use synchronized list, probably we will share the list between multile threads.
- Each thread will modify the list (add / get / set / remove - thread safe operations, as each operation is synchronized, read this to learn more).
- The iterator is not synchronized and programmer needs to take care of synchronization. If we use synchronization on our list instance then, only single thread will be able to get access to the list. If it is a bit confusion for you, learn more about synchronize keyword in java.
- Very often if we iterate a lot over synchronized list we should checkout the
CopyOnWriteArrayList
from (java.util.concurrent.CopyOnWriteArrayList
package). We will get better performance.
Full example
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class Example {
public static void main(String[] args) {
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
// now we can safely use this list between different threads
// as all methods of this list are synchronized
syncList.add("A");
syncList.addAll(Arrays.asList("B", "C"));
synchronized (syncList) {
Iterator<String> iterator = syncList.iterator(); // Must be in synchronized block
while (iterator.hasNext()) {
System.out.println(iterator.next());
// other operations
}
}
}
}
Let's take a look at java docs of Collections.synchronizedList()
method
// It is imperative that the user manually synchronize on the returned list when iterating over it:
List list = Collections.synchronizedList(new ArrayList());
synchronized (list) {
Iterator i = list.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}
We can take a look at implementation of SynchronizedList
:
public ListIterator<E> listIterator() {
return list.listIterator(); // Must be manually synched by user
}
public ListIterator<E> listIterator(int index) {
return list.listIterator(index); // Must be manually synched by user
}