Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

131
Views
How to make operations on the value of a concurrent map atomic?

Let's say I have the following field inside of a class:

ConcurrentHashMap<SomeClass, Set<SomeOtherClass>> myMap = new ConcurrentHashMap<SomeClass, Set<SomeOtherClass>>();

An instance of this class is shared among many threads.

If I want to add or remove an element from a set associated with a key, I could do:

Set<SomeOtherClass> setVal = myMap.get(someKeyValue);
setVal.add(new SomeOtherClass());

The get operation is atomic, therefore thread-safe. However, there's no guarantee that, in between the get and the add instruction, some other thread won't modify the structure messing with the first one's execution.

What would be the best way to make the whole operation atomic?

Here's what I've come up with, but I don't believe it to be very efficient (or to be making the best use out of Java's structures):

I have a ReentrantLock field, so my class looks like this:

class A {
    ReentrantLock lock = new ReentrantLock();
    ConcurrentHashMap<SomeClass, Set<SomeOtherClass>> myMap = new ConcurrentHashMap<SomeClass, Set<SomeOtherClass>>();
}

Then the method call looks something like this:

lock.lock();
Set<SomeOtherClass> setVal = myMap.get(someKeyValue);
synchronized(setVal) {
    lock.unlock();
    setVal.add(new SomeOtherClass());
}

The idea being that we let go of the lock once we have made sure no one else will access the Set we're trying to modify. However, I don't think this is making the best use of the ConcurrentMap or that it makes much sense to have a lock, a concurrent structure, and a synchronized block all used to achieve one operation.

Is there a better way to go about this?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

ConcurrentHashMap guarantees that the entire method invocation of compute (or computeIfAbsent or computeIfPresent) is done atomically. So, e.g., you could do something like this:

myMap.compute(someKeyValue, (k, v) -> {v.add(new SomeOtherClass()); return v;});

Note:
Using compute is analogous to the original snippet that assumes that somKeyValue is present in the map. Using computeIfPresent is probably safer, though.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!