no

Java Smart Locking with ReentrackLock and LoadingCache

Lock your code smartly using ReentrantLock and LoadingCache from the Guava library. What if you want to lock an update-database operation ba...

Lock your code smartly using ReentrantLock and LoadingCache from the Guava library. What if you want to lock an update-database operation base on a given id as a parameter? For example, you have an application that is update-heavy, and multiple requests come all the time. Update request with id parameter 1 and 2 should be fine as they are updating 2 separate records in the database, but what if both requests have id=1 comes at the same time? Then, there might be an issue as we will not know which value will be the final version.

1. Introduction

In this code example, I'll share a code that uses ReentrantLock with LoadingCache. LoadingCache will have String and ReentrantLock as parameters, String is the key.

2. Actual Code

package com.czetsuya.lock;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

public class KeyLock {

	public final static int THREAD_POOL_SIZE = 10;

	public static Map<String, Integer> mapOfHashTableObjects = null;

	private static LoadingCache<String, ReentrantLock> lockCache = CacheBuilder //
			.newBuilder() //
			.build(new CacheLoader<String, ReentrantLock>() {
				@Override
				public ReentrantLock load(String key) {
					return new ReentrantLock();
				}
			});

	public static void lock(String key) {

		try {
			lockCache.getUnchecked(key).tryLock(10, TimeUnit.MINUTES);

		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public static void unlock(String key) {
		lockCache.getUnchecked(key).unlock();
	}

	public static void main(String args[]) {

		try {
			mapOfHashTableObjects = new HashMap<String, Integer>();
			new KeyLock().performTest();
			System.out.println(mapOfHashTableObjects);

		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void updateMap(Integer randomNo) {

		String strKey = String.valueOf(randomNo);
		KeyLock.lock(strKey);
		try {
			mapOfHashTableObjects.put(strKey, randomNo);

		} finally {
			KeyLock.unlock(strKey);
		}
	}

	public void performTest() throws InterruptedException {

		ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);

		for (int j = 0; j < THREAD_POOL_SIZE; j++) {
			executorService.execute(new Runnable() {
				@Override
				public void run() {

					for (int i = 0; i < 100000; i++) {
						Integer randomNo = (int) Math.ceil(Math.random() * 50000);
						updateMap(randomNo);
					}
				}
			});
		}

		executorService.shutdown();

		executorService.awaitTermination(Integer.MAX_VALUE, TimeUnit.MINUTES);
	}
}

Related

coding 6424502171532384058

Post a Comment Default Comments

item