运行时遵循代码,永远不会终止并陷入无休止循环。
我不确定它在哪里卡住了。
有趣的是,当我将AaAa更改为AAAA时,一切都像预期的那样正常工作。
public class Test {
public static void main(String[] args) {
Map<String, Integer> map = new ConcurrentHashMap<>(16);
map.computeIfAbsent(
"AaAa",
key -> {
return map.computeIfAbsent(
"BBBB",
key2 -> 42);
}
);
}
}有人能帮我理解这个行为吗?
发布于 2017-05-09 13:46:55
"AaAa"和"BBBB"具有相同的hashCode() - 2031744。因此,这两个关键点被映射到Map的同一个bin。
外部map.computeIfAbsent会锁定该bin,而内部map.computeIfAbsent会在锁释放之前尝试锁定它-因此出现了死锁。
发布于 2017-05-09 14:27:44
只要两个不同的对象有相同的哈希码,我们就称其为collision。
冲突并不重要,它只是意味着单个存储桶中有多个对象,因此HashMap查找必须再次查找才能找到正确的对象。大量的冲突会降低系统的性能,但它们不会导致错误的结果。
但是如果你把哈希码错误地当成了一个对象的唯一句柄,比如将它用作Map,中的一个键,那么你有时会得到错误的对象。
在Java中有4,294,967,296划分(2^32 int值)。有40亿个插槽,碰撞似乎是极不可能的,对吧?,因为尽管碰撞很少,但它们是不可避免的。例如,字符串"Aa"和"BB"生成相同的hashCode: 2112,"AaAa"和"BBBB"具有相同的hashCode() - 2031744以及更多。
在运行的进程中,相等的对象必须具有相同的散列代码
请注意,这并不意味着存在以下常见的误解:
散列码相同的对象必须具有不同的散列码-具有相同散列码的WRONG!
https://stackoverflow.com/questions/43861945
复制相似问题