Concurrent Collections in Java

🚨 The Problem with Standard Collections

In multithreaded environments, using standard collections like ArrayList, HashMap, or HashSet can lead to data corruption, inconsistent state, or ConcurrentModificationException.

Example Problem:

List<String> list = new ArrayList<>();
// Multiple threads adding/removing elements —> Race condition

✅ The Solution: Concurrent Collections

Java’s java.util.concurrent package provides thread-safe alternatives to standard collections that allow safe access and updates by multiple threads simultaneously.


🧰 Popular Concurrent Collections (Cheat Sheet)

Collection Thread-Safe? Key Features
ConcurrentHashMap Fast, thread-safe, non-blocking reads
CopyOnWriteArrayList Best for frequent reads, rare writes
ConcurrentLinkedQueue Non-blocking queue for FIFO operations
ConcurrentSkipListMap Thread-safe, sorted map
BlockingQueue (ArrayBlockingQueue, LinkedBlockingQueue) Supports producer-consumer model with blocking

🔍 1. ConcurrentHashMap

A high-performance alternative to HashMap in multithreading.

ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("Java", 100);
System.out.println(map.get("Java"));
 

Features:

  • No locking on read operations
  • Uses internal segment locks for writes
  • Null keys/values are not allowed

🔍 2. CopyOnWriteArrayList

Useful when read operations vastly outnumber writes.

CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("CertifiKation");
System.out.println(list.get(0));

Internals:

  • On each write, the entire array is copied
  • Safe for iteration even during concurrent modifications

🔍 3. ConcurrentLinkedQueue

Non-blocking, thread-safe queue implementation.

ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
queue.add("Task1");
System.out.println(queue.poll()); // Removes and returns head

🔍 4. BlockingQueue – Producer/Consumer Model

BlockingQueue<String> queue = new ArrayBlockingQueue<>(5);

// Producer
new Thread(() -> {
    try {
        queue.put("data");
    } catch (InterruptedException e) {}
}).start();

// Consumer
new Thread(() -> {
    try {
        String item = queue.take();
    } catch (InterruptedException e) {}
}).start();


⚖️ Comparison: SynchronizedMap vs ConcurrentHashMap

Feature Collections.synchronizedMap() ConcurrentHashMap
Locking Whole map Fine-grained (segments)
Performance Slower Faster
Nulls Allowed Not allowed

💡 When to Use What?

  • Use ConcurrentHashMap for high-speed shared caches
  • Use CopyOnWriteArrayList when many threads read and few write
  • Use BlockingQueue for task queues
  • Avoid using Vector or Hashtable in modern Java — they're outdated

🧠 Summary

Concurrent collections are a powerful tool for writing safe, efficient, and scalable multithreaded Java programs. They help avoid boilerplate synchronization and are optimized for high-concurrency scenarios.

Back to blog

Leave a comment

Please note, comments need to be approved before they are published.