Reputation: 33
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
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