user10389998
user10389998

Reputation: 33

Stealing a reference from ConcurrentHashMap before removing it. Correctness

ConcurrentHashMap does not expose possibility to remove element conditionally and get it. So, I implement it on my own:

private final ConcurrentHashMap<UUID, MyClass> map = new ConcurrentHashMap<>();

public MyClass removeIfAndGet(UUID key){
    final MyClass[] arr = new MyClass[1];

    return map.computeIfPresent(key, (x, v) -> {
        if(v.isDone()){   // MyClass::isDone is thread-safe
            arr[0] = v;   // let's capture (steal) it!
            return null;  // let's remove it from a map!
        }
        return v;         // v does not satisfy our requirement, don't remove that. 
    });
}

Is it ok? I have some doubts because of not nice "stealing" a reference before removing it. Is it safe and correct (also in multithreading terms?). Yes, I know that it is necessary to MyClass be thread-safe itself.

P.S. Can I do it better?

Upvotes: 2

Views: 64

Answers (1)

Evris Tzam
Evris Tzam

Reputation: 188

Why don't you create your own ConcurrentHashMap implementation by overriding the computeIfPresent() method and have it retrieving the current mapping, if any. Then, invoke the super implementation (which invokes the parent's computeIfPresent method) and if it that returns null, then return the mapping you have retrieved.

You can take a look on how computeIfPresent is implemented, and do something similar in your own computeIfPresent method, but instead returning what you want. It can still be thread-safe.

Upvotes: 1

Related Questions