【发布时间】:2015-01-22 03:08:49
【问题描述】:
我们有一个名为 Subscriber 的类,它扩展了“HashMap”。我们在一个列表中有许多此类的实例,每个实例都有一组设置到地图的条目,其中一个是“状态”。
我们的程序正在通过调用订阅服务器上的一个方法来更新“状态”值,该方法对 HashMap 进行简单的放置。
我们的程序可以运行数天(数周)而没有任何问题,但有时我们会在系统的其他一些部分看到奇怪的行为,这些部分使用来自 HashMap 的数据。对我们来说,一个或多个订阅者实例中似乎存在重复键。
我们设法创建了一个 jmap 转储,并且基于该转储,当我在 VisualVM 中查看转储时,它会查找我们设置了两次“状态”。
我们目前正在运行 Java 版本:1.7.0_25 (Oracle)
这怎么可能?还是我看错了 VisualVM?
【问题讨论】:
-
你是从多个线程写入地图吗?
-
-
HashMap 不是线程安全的。谷歌了解更多详细信息,您需要从一个线程访问它,或者使用 ConcurrentHashMap 代替。无论如何,从 HashMap 继承是一个非常值得怀疑的做法。
-
@user3074713:众所周知,线程问题很难重现。但从根本上说,如果你在多个线程中使用一个类,而它说不这样做,你至少不能排除这是问题的原因。考虑使用线程安全映射实现添加锁定。
-
同意扩展HashMap的做法。此类旨在有效地将键映射到值。除非这也是订阅者类的主要目的,否则扩展 HashMap 表明设计不佳。请记住,extends 表示“is-a”关系;除非说“Subscriber is a HashMap”有意义,否则它可能是错误的设计。我怀疑“Subscriber has a HashMap”更合适。
标签: java hashmap hashcode visualvm jmap