8336926: jdk/internal/util/ReferencedKeyTest.java can fail with ConcurrentModificationException

Reviewed-by: bpb, shade, dfuchs
This commit is contained in:
Roger Riggs 2024-08-08 16:53:38 +00:00
parent 53c9f037fb
commit bfb75b9626

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -219,8 +219,14 @@ public final class ReferencedKeyMap<K, V> implements Map<K, V> {
@Override @Override
public V get(Object key) { public V get(Object key) {
Objects.requireNonNull(key, "key must not be null");
removeStaleReferences(); removeStaleReferences();
return getNoCheckStale(key);
}
// Internal get(key) without removing stale references that would modify the keyset.
// Use when iterating or streaming over the keys to avoid ConcurrentModificationException.
private V getNoCheckStale(Object key) {
Objects.requireNonNull(key, "key must not be null");
return map.get(lookupKey(key)); return map.get(lookupKey(key));
} }
@ -291,7 +297,7 @@ public final class ReferencedKeyMap<K, V> implements Map<K, V> {
public Set<Entry<K, V>> entrySet() { public Set<Entry<K, V>> entrySet() {
removeStaleReferences(); removeStaleReferences();
return filterKeySet() return filterKeySet()
.map(k -> new AbstractMap.SimpleEntry<>(k, get(k))) .map(k -> new AbstractMap.SimpleEntry<>(k, getNoCheckStale(k)))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
@ -335,7 +341,7 @@ public final class ReferencedKeyMap<K, V> implements Map<K, V> {
public String toString() { public String toString() {
removeStaleReferences(); removeStaleReferences();
return filterKeySet() return filterKeySet()
.map(k -> k + "=" + get(k)) .map(k -> k + "=" + getNoCheckStale(k))
.collect(Collectors.joining(", ", "{", "}")); .collect(Collectors.joining(", ", "{", "}"));
} }