我们有一个名为Subscriber的类,它扩展了“HashMap”。我们在列表中有许多此类的实例,每个实例都有一组设置为映射的条目,其中一个是“状态”。
我们的程序通过调用Subscriber上的方法更新“status”值,该方法对HashMap进行了简单的放置。
我们的程序可以运行多天(几周)而没有任何问题,但有时我们在系统的其他部分中看到了使用HashMap数据的奇怪行为。对我们来说,看起来在一个或多个Subscriber实例中存在重复的密钥。
我们设法创建一个jmap转储,并且根据转储,它查找我在VisualVM中查看转储时设置了两次“status”。
我们目前正在运行Java版本:1.7.0_25(Oracle)
这怎么可能?或者我读错了VisualVM吗?
答案 0 :(得分:1)
除了线程问题之外,还有一条明确的路径:
class Key implements CharSequence {
private byte[] key;
public Key(String key) {
// Take a copy of the bytes of the string.
this.key = key.getBytes();
}
@Override
public int length() {
return key.length;
}
@Override
public char charAt(int index) {
return (char) key[index];
}
@Override
public CharSequence subSequence(int start, int end) {
return new Key(new String(key).substring(start, end));
}
// Allow the key to change.
public void setKey(String newValue) {
key = newValue.getBytes();
}
@Override
public String toString() {
return new String(key);
}
}
public void test() {
Map<CharSequence, String> testMap = new HashMap<>();
Key aKey = new Key("a");
Key bKey = new Key("b");
testMap.put(aKey, "a");
testMap.put(bKey, "b");
bKey.setKey("a");
System.out.println(testMap.keySet());
}
这实质上是使地图的键可变,因此可以在 后将它们添加到地图中。
虽然这可能不是您面临的问题(更多可能是多线程问题)但这是对我的HashMap如何重复密钥的真正答案?。< / p>