The synchronizedCollection()
method in Java is a utility method provided by the java.util.Collections
class. It returns a synchronized (thread-safe) collection backed by the specified collection. This method is useful when you need to ensure that a collection is thread-safe in a concurrent environment.
Table of Contents
- Introduction
synchronizedCollection()
Method Syntax- Examples
- Basic Usage of
synchronizedCollection()
- Using
synchronizedCollection()
with Custom Classes
- Basic Usage of
- Real-World Use Case
- Conclusion
Introduction
The Collections.synchronizedCollection()
method provides a way to wrap a given collection with synchronized access, ensuring that only one thread can access the collection at a time. This is crucial in concurrent applications where multiple threads might try to modify the collection simultaneously, leading to race conditions or inconsistent data.
The returned collection is a synchronized view of the specified collection, meaning that all the operations on the collection are synchronized using the collection’s intrinsic lock. This includes operations such as adding, removing, or iterating over the elements.
synchronizedCollection() Method Syntax
The syntax for the synchronizedCollection()
method is as follows:
public static <T> Collection<T> synchronizedCollection(Collection<T> c)
Parameters:
c
: The collection to be wrapped in a synchronized view.
Returns:
- A synchronized (thread-safe) collection backed by the specified collection.
Throws:
NullPointerException
if the specified collection is null.
Examples
Basic Usage of synchronizedCollection()
The following example demonstrates how to use the synchronizedCollection()
method to create a synchronized view of a collection.
Example
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class SynchronizedCollectionExample {
public static void main(String[] args) {
// Create a regular ArrayList
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");
// Create a synchronized (thread-safe) collection backed by the ArrayList
Collection<String> synchronizedList = Collections.synchronizedCollection(list);
// Display the synchronized collection
System.out.println("Synchronized Collection: " + synchronizedList);
// Use synchronized block for iteration to ensure thread safety
synchronized (synchronizedList) {
Iterator<String> iterator = synchronizedList.iterator();
while (iterator.hasNext()) {
System.out.println("Element: " + iterator.next());
}
}
}
}
Output:
Synchronized Collection: [Apple, Banana, Cherry]
Element: Apple
Element: Banana
Element: Cherry
Using synchronizedCollection() with Custom Classes
You can also use the synchronizedCollection()
method with collections containing instances of custom classes.
Example
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
class Student {
String name;
Student(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public class CustomSynchronizedCollectionExample {
public static void main(String[] args) {
// Create a list of students
List<Student> students = new ArrayList<>();
students.add(new Student("Amit"));
students.add(new Student("Neha"));
students.add(new Student("Raj"));
// Create a synchronized (thread-safe) collection backed by the list of students
Collection<Student> synchronizedStudents = Collections.synchronizedCollection(students);
// Display the synchronized student collection
System.out.println("Synchronized Student Collection: " + synchronizedStudents);
// Use synchronized block for iteration to ensure thread safety
synchronized (synchronizedStudents) {
Iterator<Student> iterator = synchronizedStudents.iterator();
while (iterator.hasNext()) {
System.out.println("Student: " + iterator.next());
}
}
}
}
Output:
Synchronized Student Collection: [Amit, Neha, Raj]
Student: Amit
Student: Neha
Student: Raj
Explanation:
-
Synchronized View: The
synchronizedCollection()
method returns a synchronized view of the specified collection, ensuring thread-safe access. -
Synchronized Block: When iterating over the synchronized collection, a synchronized block is used to avoid concurrent modification exceptions and ensure thread safety.
-
Custom Class: The method works with custom class instances, allowing you to create synchronized collections with user-defined objects.
Real-World Use Case
Thread-Safe Access to a Shared Resource
In real-world applications, the synchronizedCollection()
method can be used to manage thread-safe access to shared resources, such as a collection of tasks in a multi-threaded environment.
Example
Imagine a scenario where you need to manage a shared collection of tasks in a concurrent application.
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
class Task {
String description;
Task(String description) {
this.description = description;
}
@Override
public String toString() {
return description;
}
}
public class TaskManager {
private final Collection<Task> tasks;
public TaskManager() {
// Initialize the task collection and wrap it in a synchronized view
this.tasks = Collections.synchronizedCollection(new ArrayList<>());
}
public void addTask(Task task) {
tasks.add(task);
}
public void removeTask(Task task) {
tasks.remove(task);
}
public void displayTasks() {
// Use synchronized block for iteration to ensure thread safety
synchronized (tasks) {
Iterator<Task> iterator = tasks.iterator();
while (iterator.hasNext()) {
System.out.println("Task: " + iterator.next());
}
}
}
public static void main(String[] args) {
TaskManager taskManager = new TaskManager();
// Add tasks to the manager
taskManager.addTask(new Task("Review code"));
taskManager.addTask(new Task("Write tests"));
taskManager.addTask(new Task("Deploy application"));
// Display all tasks
System.out.println("Task List:");
taskManager.displayTasks();
}
}
Output:
Task List:
Task: Review code
Task: Write tests
Task: Deploy application
Explanation:
-
Task Manager: The
TaskManager
class manages a collection of tasks, ensuring thread-safe access by wrapping the collection in a synchronized view. -
Concurrent Environment: The
synchronizedCollection()
method is used to synchronize access to the shared collection, preventing race conditions and ensuring data consistency.
Conclusion
The Collections.synchronizedCollection()
method is a powerful utility for creating synchronized (thread-safe) collections in Java. By providing a simple way to wrap collections with synchronized access, it enhances the flexibility and safety of your code in concurrent environments. This method is particularly valuable in scenarios where you need to manage shared resources or ensure thread-safe access to collections, improving the robustness and maintainability of your Java applications.