Synchronized collections are traditional collections that have been made thread - safe by synchronizing each individual method call. When a thread accesses a synchronized collection, it acquires a lock on the collection object. This ensures that only one thread can access the collection at a time, preventing data corruption due to concurrent access. However, this also means that other threads have to wait for the lock to be released, which can lead to performance bottlenecks.
Concurrent collections, on the other hand, are designed to handle concurrent access more efficiently. They use advanced techniques such as lock - striping and non - blocking algorithms. Instead of locking the entire collection, they allow multiple threads to access different parts of the collection simultaneously, reducing contention and improving performance.
Java provides several ways to create synchronized collections. One common way is to use the Collections.synchronizedXXX()
methods. For example, to create a synchronized List
, we can do the following:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SynchronizedListExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
List<String> synchronizedList = Collections.synchronizedList(list);
synchronizedList.add("Element 1");
System.out.println(synchronizedList.get(0));
}
}
ConcurrentModificationException
.import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class SynchronizedListIteration {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
List<String> synchronizedList = Collections.synchronizedList(list);
synchronizedList.add("Item 1");
synchronizedList.add("Item 2");
synchronized (synchronizedList) {
Iterator<String> iterator = synchronizedList.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
}
Java’s java.util.concurrent
package provides a variety of concurrent collections. For example, ConcurrentHashMap
can be used as a thread - safe alternative to HashMap
.
import java.util.concurrent.ConcurrentHashMap;
public class ConcurrentHashMapExample {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("Key 1", 1);
Integer value = map.get("Key 1");
System.out.println(value);
}
}
putIfAbsent()
method in ConcurrentHashMap
can be used to add a key - value pair only if the key does not already exist.import java.util.concurrent.ConcurrentHashMap;
public class ConcurrentHashMapPutIfAbsent {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.putIfAbsent("Key 1", 1);
Integer value = map.get("Key 1");
System.out.println(value);
}
}
In Java multithreading, both synchronized and concurrent collections play important roles in managing shared resources. Synchronized collections provide a simple way to make traditional collections thread - safe, but they may suffer from performance bottlenecks under high concurrency. Concurrent collections, on the other hand, are designed to handle concurrent access more efficiently using advanced techniques. By understanding the differences between these two types of collections and following the best practices, developers can write more efficient and reliable multithreaded applications.