修改映射并迭代键集时,Java ConcurentMap keySet()问题

时间:2009-03-27 11:57:56

标签: java concurrency map

快速背景我有一个并发映射,我用它来缓存一些经常变化的值(仍然值得从测试中缓存它们)。我想通过检查值中的过期时间来定期从我的缓存中逐出项目。我使用keySet()方法获取对我所有键的引用,然后检查值,如果过期我删除它们。在其他线程中,正在不断查询和更新(删除)缓存。

从keySet()的javadocs中,它提到了我在迭代键集时是否更改了地图设置结果是未定义的。显然我想要一种定义的方法来处理这个,所以结果是有效的。是否足以将Set传递给HashSet然后迭代这个集合,因为我理解这个集合将不会被映射支持,这是否浪费了内存的方式呢?任何想法都赞赏。

不幸的是,我的逐出器不是从并发映射中删除项目的唯一方法,所以我说我需要在迭代之前将keySet复制到另一个Set。

提前致谢

编辑:事实证明我正在读取Map keySet()方法的javadoc而不是ConcurrentMap keySet()。谢谢我的坏事:)。

  

返回键的set视图   包含在这张地图中。这套是   由地图支持,所以改变了   地图反映在集合中,和   反之亦然。如果地图被修改   而对集合的迭代是在   进步(除了通过   迭代器自己的删除操作),.   迭代的结果是   未定义。集支持元素   删除,删除   来自地图的相应映射,   通过Iterator.remove,Set.remove,   removeAll retainAll,并清除   操作。它不支持   添加或添加所有操作。

2 个答案:

答案 0 :(得分:6)

您使用的是the Java Concurrent HashMap吗?从keySet()文档看,它看起来像你认为有用的方式。

  

返回此映射中包含的键的set视图。该集由地图支持,因此对地图的更改将反映在集中,反之亦然。该集支持元素删除,它通过Iterator.remove,Set.remove,removeAll,retainAll和clear操作从此映射中删除相应的映射。它不支持add或addAll操作。视图的返回迭代器是一个“弱一致”的迭代器,它永远不会抛出ConcurrentModificationException,并保证遍历构造迭代器时存在的元素,并且可能(但不保证)反映构造之后的任何修改。

即。你可以删除东西,你应该没事。

如果您没有使用此实现,那么您正在使用哪些(以及为什么?不好笑,但知道您做出选择的原因会很有趣)

答案 1 :(得分:0)

如果一个LRU缓存能够很好地满足你的需求,请查看LinkedHashMap - 它使实现LRU缓存变得微不足道,然后你可以通过调用{{3}来包装它来使结果成为线程安全的}}

相关问题