有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何安全地清理并发映射

我正试图解决一个对我来说很常见的问题,但我找不到好的解决办法

在非常并发的环境中,当客户端会话被破坏时,我需要正确地释放资源。以下是输入:

  • 我使用ConcurrentHashMap来存储所有分配的资源,这里需要map来索引资源
  • 在销毁会话时,有时会从挂起的任务中分配新的资源,我希望最终也释放这些任务

以下是我当前的解决方案:

while (!resourceMap.isEmpty()) {
    Map<Integer, Resource> toDestroy = new HashMap<>(resourceMap);
    for (Resource resource : toDestroy.values()) {
        resource.destroy();
    }
    resourceMap.keySet().removeAll(toDestroy.keySet());
}

它的存在只是因为ConcurrentHashMap#values#iterator并不总是反映对resourceMap的并发put。我不喜欢此代码,更喜欢类似队列的代码,但不幸的是ConcurrentMap没有提供类似的内容:

while ((Map.Entry<String, Resource> entry = resourceMap.removeAny()) != null) {
    entry.value().destroy();
}

我正在寻找类似于上面的类似队列的代码的解决方案,或者任何解决这个问题的替代方法


共 (1) 个答案

  1. # 1 楼答案

    I do not like this code and would prefer queue-like code, but unfortunately ConcurrentMap does not provide anything like this ...

    我只想使用迭代器,但我又不是Java8的粉丝

    while (!resourceMap.isEmpty()) {
        Iterator<Resource> iterator = resourceMap.values().iterator();
        while (iterator.hasNext()) {
           Resource resource = iterator.next();
           iterator.remove();
           resource.destroy();
        }
    }
    

    需要注意的是,此模型中存在竞争条件。有人可以得到资源,去使用它,但同时它正在被这个线程破坏