Reputation: 10161
I am trying to solve a problem which seems quite common to me, but I could not find good solution for it.
In a very concurrent environment I need to release resources correctly when client session is destroyed. Here is input:
ConcurrentHashMap
to store all allocated resources, map is required here to index resourcesHere is my current solution:
while (!resourceMap.isEmpty()) {
Map<Integer, Resource> toDestroy = new HashMap<>(resourceMap);
for (Resource resource : toDestroy.values()) {
resource.destroy();
}
resourceMap.keySet().removeAll(toDestroy.keySet());
}
Which exists only because ConcurrentHashMap#values#iterator
does not always reflect concurrent puts to resourceMap
. I do not like this code and would prefer queue-like code, but unfortunately ConcurrentMap
does not provide anything like this:
while ((Map.Entry<String, Resource> entry = resourceMap.removeAny()) != null) {
entry.value().destroy();
}
I am looking for solution which is similar to queue-like code above or any alternative approaches to this problem.
Upvotes: 1
Views: 500
Reputation: 116908
I do not like this code and would prefer queue-like code, but unfortunately ConcurrentMap does not provide anything like this ...
I would just use an iterator but then again I'm not a Java 8 fan.
while (!resourceMap.isEmpty()) {
Iterator<Resource> iterator = resourceMap.values().iterator();
while (iterator.hasNext()) {
Resource resource = iterator.next();
iterator.remove();
resource.destroy();
}
}
It's important to note that there are race conditions in this model. Someone could get the resource, go to use it, but at the same time it is being destroyed by this thread.
Upvotes: 1