"HashMap"을 확장하는 Subscriber라는 클래스가 있습니다. 이 클래스의 많은 인스턴스가 목록에 있으며 각 인스턴스에는지도에 설정된 항목 집합이 있으며 그 중 하나는 '상태'입니다.어떻게 내 HashMap에 중복 키가 있습니까?
우리 프로그램은 구독자의 메서드를 호출하여 "상태"값을 업데이트합니다.이 메서드는 HashMap에 단순하게 넣습니다.
우리 프로그램은 아무런 문제없이 여러 날 (주) 동안 실행될 수 있지만, HashMap의 데이터를 사용하는 시스템의 다른 부분에서는 이상한 동작을 보았을 수 있습니다. 하나 이상의 Subscriber 인스턴스에 중복 키가있는 것 같습니다.
우리는 jmap 덤프를 만들었고 덤프를 기반으로 VisualVM에서 덤프를 볼 때 "상태"가 두 번 설정되어 있는지 찾습니다.
우리는 현재 Java 버전 실행 : 1.7.0_25 (오라클)
어떻게 이런 일이 가능를? 또는 VisualVM을 잘못 읽었습니까? 그들은지도에 추가 후가 변경 될 수 있습니다
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());
}
이 본질적으로 변경 가능한지도의 열쇠를하고있다 :
여러 스레드에서지도에 쓰고 있습니까? –
지도의 열쇠로 사용되는 클래스는 무엇입니까? – AlexR
@JonSkeet 예 전 – goddva