In this Q&A, we'll go over few options to synchronize access to a collection
I - Use Collections.synchronized methods
Use java.util.Collections.synchronized<Map|List|Set> classes. Synchronized classes wrap the underlying implementation in a synchronized section.
Example:
List<Integer> l = new ArrayList<>();
for(int i=0; i < 1000; ++i) {
l.add(i);
}
List<Integer> l2 = Collections.synchronizedList(l);
II - Use Copy on Write ArrayList
Use copy on write array list. This is efficient for mostly read only collections. Write operation involves copying the entire collection.
III - Use java.util.Concurrent* classes
Java provides fine grained concurrency control with the following classes: ConcurrentHashMap, ConcurrentLinkedQueue and ConcurrentLinkedDequeue. These classes have full read concurrency and high expected update concurrency.
While Java ConcurrentHashMap there's no ConcurrentHashSet class. But, we can get a concurrent set from a ConcurrentHashMap. See code snippet below.
ConcurrentHashMap<String, Boolean> chm = new ConcurrentHashMap<>();
chm.put("1", true);
chm.put("2", false);
assertEquals("size match", 2, chm.size());
assertEquals("Key not found", false, chm.containsKey("3"));
// Set is thread safe. Read operations are fully concurrent
// updates have high expected concurrrency
// Set updates result in ConcurrentHashMap update
Set<String> s = chm.keySet(Boolean.TRUE);
s.add("3");
assertEquals("Key found", true, chm.containsKey("3"));
Another way to create a Set is to use the Collections.newSetFromMap method.
While Java ConcurrentHashMap there's no ConcurrentHashSet class. But, we can get a concurrent set from a ConcurrentHashMap. See code snippet below.
ConcurrentHashMap<String, Boolean> chm = new ConcurrentHashMap<>();
chm.put("1", true);
chm.put("2", false);
assertEquals("size match", 2, chm.size());
assertEquals("Key not found", false, chm.containsKey("3"));
// Set is thread safe. Read operations are fully concurrent
// updates have high expected concurrrency
// Set updates result in ConcurrentHashMap update
Set<String> s = chm.keySet(Boolean.TRUE);
s.add("3");
assertEquals("Key found", true, chm.containsKey("3"));
Another way to create a Set is to use the Collections.newSetFromMap method.
IV Use Vector or HashTable
This is not a desired option as as these classes are not part of the Collections framework.
Comments
Post a Comment