Insertion into ConcurrentHashMap, Thread-safe and Concurrent Collections


Concurrent Collections

A concurrent collection is a [collection][1] which permits access by more than one thread at the same time. Different threads can typically iterate through the contents of the collection and add or remove elements.

Thread-safe Collections

By default, the various Collection types are not thread-safe.

However, it's fairly easy to make a collection thread-safe.

List<String> threadSafeList = Collections.synchronizedList(new ArrayList<String>());
Set<String> threadSafeSet = Collections.synchronizedSet(new HashSet<String>());
Map<String, String> threadSafeMap = Collections.synchronizedMap(new HashMap<String, String>());

When you make a thread-safe collection, you should never access it through the original collection, only through the thread-safe wrapper.

Version ≥ Java SE 5

Starting in Java 5, java.util.collections has several new thread-safe collections that don't need the various Collections.synchronized methods.

List<String> threadSafeList = new CopyOnWriteArrayList<String>();
Set<String> threadSafeSet = new ConcurrentHashSet<String>();
Map<String, String> threadSafeMap = new ConcurrentHashMap<String, String>();

Insertion into ConcurrentHashMap

public class AnotherConcurrentHashMapExample
{
	public static void main(String[] args)
	{
		ConcurrentHashMap<Integer, AnotherObject> anotherConcurrentHashMap = new ConcurrentHashMap<>();
		AnotherObject anotherValue = new AnotherObject();
		Integer anotherKey = 42;
		AnotherObject previousAnotherValue = anotherConcurrentHashMap.putIfAbsent(42, anotherValue);
		if (previousAnotherValue != null)
		{
			// Then some other value was mapped to anotherKey = 42.
			// 'anotherValue' that was passed to putIfAbsent method is NOT inserted.
			// Decide how you wish to handle this situation.
		}
		else
		{
			// 'anotherValue' reference is mapped to anotherKey = 42.
		}
	}
}

Concurrent Collections

Concurrent collections are a generalization of thread-safe collections, that allow for a broader usage in a concurrent environment.

While thread-safe collections have safe element addition or removal from multiple threads, they do not necessarily have safe iteration in the same context (one may not be able to safely iterate through the collection in one thread, while another one modifies it by adding/removing elements).

This is where concurrent collections are used.

As iteration is often the base implementation of several bulk methods in collections, like addAll, removeAll, or also collection copying (through a constructor, or other means), sorting, ... the use case for concurrent collections is actually pretty large.

For example, the Java SE 5 java.util.concurrent.CopyOnWriteArrayList is a thread safe and concurrent List implementation.

public class CustomThreadSafeExample {
    public static final List<Integer> CUSTOM_LIST = new CopyOnWriteArrayList<>();
 
    public static void main(String[] args) throws InterruptedException {
        Thread writerThread = new Thread(new WriterRunnable());
        Thread readerThread = new Thread(new ReaderRunnable());
 
        writerThread.start();
        readerThread.start();
 
        writerThread.join();
        readerThread.join();
    }
 
    public static final class WriterRunnable implements Runnable {
        @Override
        public void run() {
            try {
                for (int i = 0; i < 70000; i++) {
                    CUSTOM_LIST.add(i);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
 
    public static final class ReaderRunnable implements Runnable {
        @Override
        public void run() {
            try {
                for (int i = 0; i < 15000; i++) {
                    long total = 0;
                    for (Integer inList : CUSTOM_LIST) {
                        total += inList;
                    }
                    System.out.println("Total: " + total);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Basic Programs