Skip to main content

How do I synchronize access to a collection

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: ConcurrentHashMapConcurrentLinkedQueue 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.

IV Use Vector or HashTable

This is not a desired option as as these classes are not part of the Collections framework.

Comments