The Collections.synchronizedList() method of the java.util.Collections class returns a thread-safe (synchronized) view of the specified list. It wraps an existing List and synchronizes all its methods, making it safe for concurrent access by multiple threads.
- Supports all List implementations such as ArrayList and LinkedList.
- Iteration must be manually synchronized.
Syntax
public static <T> List<T> synchronizedList(List<T> list)
Parameter
- list –> The list to be wrapped in a synchronized (thread-safe) list.
Return Value: Returns a synchronized (thread-safe) view of the specified list.
Example: Creating a Synchronized List of Strings
import java.util.*;
public class GFG1 {
public static void main(String[] argv) throws Exception
{
try {
// creating object of List<String>
List<String> list = new ArrayList<String>();
// populate the list
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
// printing the Collection
System.out.println("List : " + list);
// create a synchronized list
List<String> synlist = Collections
.synchronizedList(list);
// printing the Collection
System.out.println("Synchronized list is : " + synlist);
}
catch (IllegalArgumentException e) {
System.out.println("Exception thrown : " + e);
}
}
}
Output
List : [A, B, C, D, E] Synchronized list is : [A, B, C, D, E]
Explanation: The ArrayList is wrapped using Collections.synchronizedList(). The returned list synchronizes all operations, allowing multiple threads to access it safely.
Example: Creating a Synchronized List of Integers
import java.util.*;
public class GFG1 {
public static void main(String[] argv)
throws Exception
{
try {
// creating object of List<Integer>
List<Integer> list = new ArrayList<Integer>();
// populate the list
list.add(20);
list.add(30);
list.add(40);
list.add(50);
list.add(60);
// printing the Collection
System.out.println("List : " + list);
// create a synchronized list
List<Integer> synlist = Collections
.synchronizedList(list);
// printing the Collection
System.out.println("Synchronized list is : " + synlist);
}
catch (IllegalArgumentException e) {
System.out.println("Exception thrown : " + e);
}
}
}
Output
List : [20, 30, 40, 50, 60] Synchronized list is : [20, 30, 40, 50, 60]
Explanation: The integer list is converted into a synchronized list. Any access to the returned list is synchronized internally, making it suitable for multi-threaded applications.
Iterating Over a Synchronized List
Although the list is synchronized, iteration must still be synchronized manually to avoid unexpected behavior.
import java.util.*;
public class GFG {
public static void main(String[] args) {
List<String> list = Collections.synchronizedList(new ArrayList<>());
list.add("Java");
list.add("Python");
list.add("C++");
synchronized (list) {
for (String s : list) {
System.out.println(s);
}
}
}
}
Output
Java Python C++
Explanation: The synchronized block ensures that no other thread modifies the list while it is being traversed.
Advantages of synchronizedList()
- Provides thread-safe access to a list.
- Prevents data inconsistency during concurrent access.
- Works with any List implementation.
- Easy to convert an existing list into a synchronized list.
- Does not require creating a new list.
Limitations
- Iteration requires manual synchronization.
- Synchronization introduces performance overhead.
- Less scalable than concurrent collections like
CopyOnWriteArrayList.