Reputation: 11154
Following code when run, never terminates and stuck in endless loop.
I am not sure where it is getting stuck.
Interesting thing is when I change AaAa
to AAAA
every thing works fine as expected.
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);
}
);
}
}
Can some one help me understanding this behavior.
Upvotes: 3
Views: 1890
Reputation: 15874
Whenever two different objects have the same hash code, we call this a collision
.
A collision is nothing critical, it just means that there is more than one object in a single bucket, so a HashMap
lookup has to look again to find the right object. A lot of collisions will degrade the performance of a system, but they won’t lead to incorrect results.
But if you mistake the hash code for a unique handle to an object, e.g use it as a key in a Map
, then you will sometimes get the wrong object.
In Java
there are 4,294,967,296
compartments (2^32
possible int
values). With 4 billion slots, collisions seem to be extremely unlikely, right? Because even though collisions are rare, they are inevitable. For example, the Strings "Aa"
and "BB"
produce the same hashCode: 2112
."AaAa"
and "BBBB"
have the same hashCode() - 2031744
and many more.
Objects that are equal must have the same hash code within a running process
Please note that this does not imply the following common misconceptions:
Upvotes: 0
Reputation: 393936
"AaAa"
and "BBBB"
have the same hashCode()
- 2031744.
Therefore both keys are mapped to the same bin of the Map.
The outer map.computeIfAbsent
locks that bin, and the inner map.computeIfAbsent
tries to lock it before the lock is released - hence the deadlock.
Upvotes: 16