Concurrent HashMap – Real life use of Concurrent HashMap

By | June 25, 2024

What is ConcurrentHashMap?

In Java, ConcurrentHashMap is a class that implements the Map<K,V> interface, and it is synchronised. When we declare a HashMap<K,V> in Java, the JVM internally assigns 16 buckets of memory to it. In ConcurrentHashMap, the lock is on each of the 16 buckets, which facilitates multiple write operations on different buckets concurrently and multiple reads from one or more buckets.

Fig 1- ConcurrentHashMap

Concurrent HashMap real life usecase

Imagine an online stock trading platform where multiple users can buy and sell stocks concurrently. In this scenario, we need to maintain the count of stocks for each company concurrently in a thread-safe manner. We can use concurrent hashmap to achieve this scenario easily. Let’s implement and understand.

Steps 1- Create StockInventory class

First, we will be creating a StockInventory class. In this class, we define a ConcurrentHashMap, stockCounts, which will store the initial count of stocks for each company. We have other utility methods for buying and selling stocks. The buyStock() method will decrease the total count of stocks for a specific company, and the sellStock() method will increase the total count of stocks.

Java
import java.util.concurrent.ConcurrentHashMap;

/**
 * 1. buyStock: reduce the count of the stocks
 * 2. sellStock: increase the count of the stocks
 * 
 * @author paulsofts
 */

public class StockInventory {
    private ConcurrentHashMap<String, Integer> stockCounts;

    public StockInventory() {
        stockCounts = new ConcurrentHashMap<>();
    }
    
    // Method to add initial stockS count
    public void addStock(String company, int count) {
    	stockCounts.put(company, count);
    }

    // Method to buy stocks
    public void buyStock(String company, int count) {
        stockCounts.merge(company, -count, Integer::sum);
    }

    // Method to sell stocks
    public void sellStock(String company, int count) {
        stockCounts.merge(company, count, Integer::sum);
    }

    // Method to get the current count of a specific company's stock
    public int getStockCount(String company) {
        return stockCounts.getOrDefault(company, 0);
    }
    
}

Step 2- Main class

In Main Class, we first initialize the initial count of stocks for each company. After that, we used the Runnable interface to create buy and sell tasks and execute them using threads. In order to make sure every thread completes its execution, we have used the join() method, which makes the main thread wait until the joining thread completes its execution. Finally, we are printing the total count of stocks for each company over the console.

Java
/**
 * 1. Initialize the initial value of stocks
 * 2. Executing buy and sell tasks using thread1, thread2, thread3 and thread4
 * 3. Using join method to make sure all tasks (threads) gets completed
 * 4. Finally, printing the total stocks count for each company
 * @author paulsofts
 */
public class Main {

	public static void initialize(String company, int count, StockInventory inventory) {
		inventory.addStock(company, count);
	}

	public static void main(String[] args) {

		// Initializing the initial value for stocks
		StockInventory inventory = new StockInventory();
		initialize("INFOSYS", 100, inventory);
		initialize("TCS", 100, inventory); 

		// Simulate stock transactions concurrently
		Runnable buyTask1 = () -> inventory.buyStock("INFOSYS", 10);
		Runnable sellTask1 = () -> inventory.sellStock("INFOSYS", 5);
		Runnable buyTask2 = () -> inventory.buyStock("TCS", 20);
		Runnable sellTask2 = () -> inventory.sellStock("TCS", 10);

		Thread thread1 = new Thread(buyTask1);
		Thread thread2 = new Thread(sellTask1);
		Thread thread3 = new Thread(buyTask2);
		Thread thread4 = new Thread(sellTask2);

		thread1.start();
		thread2.start();
		thread3.start();
		thread4.start();

		// Wait for all threads to complete
		try {
			thread1.join();
			thread2.join();
			thread3.join();
			thread4.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		// Get stock counts
		System.out.println("INFOSYS stock count: " + inventory.getStockCount("INFOSYS")); 
																							
		System.out.println("TCS stock count: " + inventory.getStockCount("TCS"));
	}
}

Step 3- Output

Concurrent HashMap
Fig 2- Output

Leave a Reply

Your email address will not be published. Required fields are marked *