快速背景我有一个并发映射,我用它来缓存一些经常变化的值(仍然值得从测试中缓存它们)。我想通过检查值中的过期时间来定期从我的缓存中逐出项目。我使用keySet()方法获取对我所有键的引用,然后检查值,如果过期我删除它们。在其他线程中,正在不断查询和更新(删除)缓存。
从keySet()的javadocs中,它提到了我在迭代键集时是否更改了地图设置结果是未定义的。显然我想要一种定义的方法来处理这个,所以结果是有效的。是否足以将Set传递给HashSet然后迭代这个集合,因为我理解这个集合将不会被映射支持,这是否浪费了内存的方式呢?任何想法都赞赏。
不幸的是,我的逐出器不是从并发映射中删除项目的唯一方法,所以我说我需要在迭代之前将keySet复制到另一个Set。
提前致谢
编辑:事实证明我正在读取Map keySet()方法的javadoc而不是ConcurrentMap keySet()。谢谢我的坏事:)。
返回键的set视图 包含在这张地图中。这套是 由地图支持,所以改变了 地图反映在集合中,和 反之亦然。如果地图被修改 而对集合的迭代是在 进步(除了通过 迭代器自己的删除操作),. 迭代的结果是 未定义。集支持元素 删除,删除 来自地图的相应映射, 通过Iterator.remove,Set.remove, removeAll retainAll,并清除 操作。它不支持 添加或添加所有操作。
答案 0 :(得分:6)
您使用的是the Java Concurrent HashMap吗?从keySet()文档看,它看起来像你认为有用的方式。
返回此映射中包含的键的set视图。该集由地图支持,因此对地图的更改将反映在集中,反之亦然。该集支持元素删除,它通过Iterator.remove,Set.remove,removeAll,retainAll和clear操作从此映射中删除相应的映射。它不支持add或addAll操作。视图的返回迭代器是一个“弱一致”的迭代器,它永远不会抛出ConcurrentModificationException,并保证遍历构造迭代器时存在的元素,并且可能(但不保证)反映构造之后的任何修改。
即。你可以删除东西,你应该没事。
如果您没有使用此实现,那么您正在使用哪些(以及为什么?不好笑,但知道您做出选择的原因会很有趣)
答案 1 :(得分:0)
如果一个LRU缓存能够很好地满足你的需求,请查看LinkedHashMap - 它使实现LRU缓存变得微不足道,然后你可以通过调用{{3}来包装它来使结果成为线程安全的}}