我正在尝试使用Java7 7的WeakHashMap,我发现它的isEmpty()方法给了我错误的结果。
import java.util.Map;
import java.util.WeakHashMap;
public class Test
{
public static void main(final String[] args)
{
final Map<String, Boolean> map = new WeakHashMap<>();
String b = new String("B");
map.put(b, true);
b = null;
System.gc();
System.out.println(map.isEmpty());
System.out.println(map.keySet().isEmpty());
System.out.println(map);
}
}实际结果:
错误
真的
{}
也就是说,
map.isEmpty()和map.keySet().isEmpty()不一致。有人能帮我理解一下吗?非常感谢。
发布于 2019-03-28 20:04:15
...This结果是快照,可能不会反映在下一次尝试访问之前将删除的未处理项,因为它们不再被引用。
因此,您希望isEmpty()在GC 之后返回正确的值,在访问后返回。下面的代码说明了这一点:
public class Scratch1 {
public static void main(final String[] args) {
final Map<String, Boolean> map = new WeakHashMap<>();
String b = new String("B");
map.put(b, true);
b = null;
System.gc();
// map not internally accessed at this point
System.out.println(map.isEmpty());
// let's access the Map's internals (and hopefully coerce
// it into removing no-longer-referenced keys)
System.out.println(map.keySet()
.isEmpty());
// map HAS now been accessed
System.out.println(map.isEmpty());
}
}产量:
false
true
true发布于 2019-03-28 19:59:14
您应该阅读WeakHashMap的javadoc。
WeakHashMap类的行为在一定程度上取决于垃圾收集器的操作,因此几个熟悉的(尽管不是必需的)Map不变量对于这个类不成立。因为垃圾收集器可以在任何时候丢弃键,所以WeakHashMap的行为可能就像一个未知的线程正在悄悄地删除条目一样。特别是,即使您在一个size实例上同步并且不调用它的任何变体方法,随着时间的推移,isEmpty方法也有可能返回较小的值,isEmpty方法可以返回false,而对于containsKey方法返回true,以及稍后对给定密钥返回false,对于get方法返回给定键的值但稍后返回null,对于put方法返回null和remove方法返回以前在映射中的键的false,以及对键集、值集合和条目集的连续检查,以依次生成较小数量的元素。
最重要的是你所看到的效果是完全有效的。
https://stackoverflow.com/questions/55405864
复制相似问题