Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ConcurrentMap entries synchronization without blocking whole map

Rest service have many customers which are not related to each other. Each customer can start voting process any time. Once customer adds first vote I create an entry in

ConcurrentMap<customerId, ConcurrentMap<voteId, voteTimestamp>> votesByCustomer;

Each vote have voteTimestamp, so when it expires - it is being removed from the map by another thread. (This removal is not a simple votesByCustomer.remove() call, it involves several subsequent calls to the votesByCustomer map, hence have to be synchronized additionally). So, the above votesByCustomer map is shared between all customers. (Implemented as a field in enum-backed singleton).

There are many operations with this map which involves several calls to votesByCustomer to be done in the atomic way. So I use syncronized(votesByCustomer) {} expression.

So when these methods are called it locks all customers.

My question is how do I write code in such a way so when I'm doing operations for one customer it doesn't look other ones.

I feel like I'm trying to solve an already solved problem, and there is a perfect API and good approach for this, but I can't really make a proper google request. Can you give some tips, please? I use Java8 and Spring.

like image 853
Eugene S Avatar asked Jul 09 '26 18:07

Eugene S


1 Answers

Perhaps you can use computeIfAbsent() to safely and quickly get the specific ConcurrentMap associated with that customer (or create a new one if none exists), then use a synchronized block on that customer-specific ConcurrentMap for all the operations that are specific to that customer.

The major danger I can see is that if your vote expiration process ever removes a customer entry from votesByCustomer then you could end up in a race condition where you record a vote to a ConcurrentHashMap that's no longer associated with that customer. So you'd have to make sure you leave an empty ConcurrentMap in there even for customers whose votes have all expired.

like image 137
StriplingWarrior Avatar answered Jul 11 '26 09:07

StriplingWarrior