Yes, it is true. HashMap.get() can cause an infinite loop. Everyone I’ve talked to didn’t believe it either, but yet there it is — right in front of my very eyes.
I'm not sure that this is true. Even if it is, the problem is not being caused by the code shown. The first method uses an infinite loop to traverse the hash buckets which are constructed as *singlely* linked lists. The second method is copying the contents of one hash table into another, presumably to handle growth. There is no situation caused by the second method where any bucket would become looped, regardless of concurrency.
The only way I can think of that an infinite loop could be caused is a situation like this:
Thread 1:
map.put("foo", "bar");
Thread 2:
map.put("baz", "biff");
Thread 1 and 2 run *simultaneously* on an unsychronized instance of HashMap. Theoretically, "foo" and "baz" could hash to the same bucket (they don't, but let's just pretend that they do). If that were the case, then both threads would attempt a linked list insertion simultaniously. Most of the time, this would just result in some lost data. However, it is *possible* in an imperative implementation of linked list that one thread would have a reference to an Entry which *should* go next in the bucket, but is superceded by the other thread before it gets a chance to setup the link. Between the two of them, it is conceivable that an Entry could point back to the *previous* entry, rather than actually going back to the head of the bucket. After that point, any reads (synchronized or otherwise) which hashed to that bucket would enter an infinite loop.
This situation would be *extremely* rare however, if it could happen at all (I haven't really analyzed the code for HashMap). What I would really like is to see some code which reproduces this case, at least some of the time.
Great fact to know about. It sounds logical that data inconsistency produces an infinite loop but have not ever thought about hitting this inside an API data structure.
voted down for not reading javadocs.. From his implementation its hard to tell how its occuring, but absolutely thread safety should be considered for any shared mutable collections.
Comments
daniel replied ago:
I'm not sure that this is true. Even if it is, the problem is not being caused by the code shown. The first method uses an infinite loop to traverse the hash buckets which are constructed as *singlely* linked lists. The second method is copying the contents of one hash table into another, presumably to handle growth. There is no situation caused by the second method where any bucket would become looped, regardless of concurrency.
The only way I can think of that an infinite loop could be caused is a situation like this:
Thread 1:
map.put("foo", "bar");
Thread 2:
map.put("baz", "biff");
Thread 1 and 2 run *simultaneously* on an unsychronized instance of HashMap. Theoretically, "foo" and "baz" could hash to the same bucket (they don't, but let's just pretend that they do). If that were the case, then both threads would attempt a linked list insertion simultaniously. Most of the time, this would just result in some lost data. However, it is *possible* in an imperative implementation of linked list that one thread would have a reference to an Entry which *should* go next in the bucket, but is superceded by the other thread before it gets a chance to setup the link. Between the two of them, it is conceivable that an Entry could point back to the *previous* entry, rather than actually going back to the head of the bucket. After that point, any reads (synchronized or otherwise) which hashed to that bucket would enter an infinite loop.
This situation would be *extremely* rare however, if it could happen at all (I haven't really analyzed the code for HashMap). What I would really like is to see some code which reproduces this case, at least some of the time.
Potatoman replied ago:
This absolutely is possibly. I've seen it in production :(
IIRC it happens when you have two threads inserting the same value and a resize happens.
toomasr replied ago:
Great fact to know about. It sounds logical that data inconsistency produces an infinite loop but have not ever thought about hitting this inside an API data structure.
ceaseoleo replied ago:
voted down for not reading javadocs.. From his implementation its hard to tell how its occuring, but absolutely thread safety should be considered for any shared mutable collections.
Voters For This Link (10)
Voters Against This Link (3)