SUGGESTED FIX
http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/main/java/util/concurrent/ArrayBlockingQueue.java?r1=1.59&r2=1.60
|
|
|
EVALUATION
The problem is fixed in ArrayBlockingQueue.java, Revision 1.60, Doug Lea's JSR-166 CVS.
http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/main/java/util/concurrent/ArrayBlockingQueue.java?r1=1.59&r2=1.60
|
|
|
EVALUATION
This bug is no longer an issue in JDK 7 b128. It has been fixed as part of the changes for CR 7005424. Adding '7-na' keyword to reflect this.
Here's what is happening (pre 7005424). Invoking remove on the iterator returned by ABQ simply tries to remove the item at the index of the item that was previously returned by the iterator, using removeAt(int). This is not correct as the item at that index may not the same item, or in this case the queue may be empty. removeAt will always decrement the count, causing it to become negative if the queue is empty. Many other operations will now cause the queue to get into a very bad state as they use if (count == 0) to determine if the queue is empty ( they assume count will never be negative ).
But how is iterator.remove being invoked, since the test does not call it directly? The test invokes retainAll ( which is inherited from AbstractCollection ). AbstractCollection.retainAll creates an iterator over the the collection and invokes remove() if the given collection does not contain the item.
Targeting this bug to JDK6, to backport the specific changes required fix the iterators remove method.
|
|
|
PUBLIC COMMENTS
I suspect the updates to the Iterator locking and logic may be the fix here, though I would expect itr.remove() to be the cause of the problem and I don't see that being used.
|
|
|
PUBLIC COMMENTS
I can reproduce this quite easily with JDK7 b125, and it is failing because count is negative. With the latest JDK7, built from JDK b128, I no longer see the problem. There were some changes to ArrayBlockingQueue that were integrated under CR 7005424. It is possible that this issue was fixed. More investigation into the root cause needs to be done to ensure it has actually been fixed.
|
|
|