Java或Google Guava中具有弱值的简单线程安全Java哈希映射?

时间:2014-06-21 17:15:58

标签: java collections map concurrency guava

我想根据他们的ID保留单个对象的地图,只是为了确保每个人都获得相同的副本。这些对象的创建很少发生,我不想要或需要并发映射的开销(这将在内部基本上保留多个映射在内存中)。但我确实需要地图来支持弱键,这样当没有人使用特定实例时,记录将从地图中删除。

那么我有什么选择? Guava MapMakerCacheBuilder创建并发映射,它使用的内存比我需要的多得多。我不需要"并发" ---我只需要线程安全。是的,我可以将并发级别设置为1,但根据API文档,这只是一个提示,将来可能会被完全忽略。

我可以使用Java Collections创建一个简单的同步HashMap并使用putIfAbsent(...),但这并没有给我弱值的好处。我可以存储弱引用,但是在访问地图时它们不会被自动删除。

如果我有一个版本的Java WeakHashMap支持弱值而不是弱键,我可以将它包装在同步映射中并完成它。

我相信很久以前Apache Commons Collections有一个允许指定弱值的地图构建器,但我们正在使用Guava。

有什么建议吗?请尽快阅读完整的问题,然后再提出我已经提到的建议。

2 个答案:

答案 0 :(得分:1)

我说这是错位优化的完美示例。您说您不需要并发,而且您不想为多个地图细分付费。但是每个这样的段只存储了一部分条目,因此每个段增加的开销不超过几百个字节,或者更少。

您说存储的对象是单例。这意味着您只需要一个这样的地图。目前,Guava的缓存创建了所请求的段数,即在您的情况下为一个(因此唯一的内存开销来自一个段数组的长度(4个字节)和一些簿记数据(类似的大小)。假设这应该变得更糟,你用concurrencyLevel(1)获得了64个细分,你可能会失去一些千字节。除非你打算像ZX Spectrum那样运行你的应用程序,否则它真的不应该物质

也许我错过了什么,也许你遗漏了一些东西。随意澄清。

答案 1 :(得分:0)

创建您自己的WeakReference并在 HashMap<key,weakObj> 中使用它。希望这可行。