[concurrency-interest] Bug in ConcurrentHashMap keyset iterator?
Adrian Tarau
adrian.tarau at gmail.com
Thu Feb 16 09:42:54 EST 2012
Good morning,
I get recently several failures in one of the processes(a remote file
collector) which looks like a bug in ConcurrentHashMap implementation. I
attached all relevant code...I do not think I misused the map but... I
searched for similar complaints but I couldn't find anything relevant -
bugs.sun.com returns noting when searching for "ConcurrentHashMap
ArrayIndexOutOfBoundsException".
Thank you,
Adrian Tarau.
I have a map declared like this:
/private final Map<Location, PriorityBlockingQueue<WorkUnit>>
workUnitsPerLocation = new ConcurrentHashMap<Location,
PriorityBlockingQueue<WorkUnit>>();/
a work unit is pushed like this:
......
Queue<WorkUnit> locationQueue = getLocationQueue(location);
boolean offer = locationQueue.offer(workUnit);
.......
private Queue<WorkUnit> getLocationQueue(Location location) {
synchronized (workUnitsPerLocation) {
PriorityBlockingQueue<WorkUnit> queue =
workUnitsPerLocation.get(location);
if (queue == null) {
queue = new PriorityBlockingQueue<WorkUnit>(100, new
WorkUnit.Comparator());
workUnitsPerLocation.put(location, queue);
}
return queue;
}
}
and a working thread(scheduled to run every 5 seconds) is scanning for
available work units, peeking one from every location(until a maximum
number of working units are running) like this:
/class WorkUnitScheduler extends AbstractWorker {
...
// volatile since the state of the iterator must be preserved
under different working threads
private volatile Iterator<Location> workUnitsIterator;
....
private Queue<WorkUnit> getNextQueue() {
for (int i = 0; i < 2; i++) {// loop twice so we go over
all possible locations
if (workUnitsIterator == null ||
!workUnitsIterator.hasNext()) {
workUnitsIterator =
workUnitsPerLocation.keySet().iterator();//start from beginning
}
while (workUnitsIterator.hasNext()) {
try {
Location location = workUnitsIterator.next();
*<--- fails here*
if (canScheduleFromLocation(location)) {//if
allowed, get next working unit from this location
return workUnitsPerLocation.get(location);
}
} catch (NoSuchElementException e) {
// no location
}
}
}
return null;
}
@Override
protected void doRun() {
....
Queue<WorkUnit> queue = getNextQueue();
if (queue == null) {
break;
}
WorkUnit workingUnit = queue.poll();
if (workingUnit == null) {
continue;
}
WorkerService.getInstance().schedule(new
DownloadUploadWorker(workingUnit));
....
}
}/
and it fails with:
/got exception java.lang.ArrayIndexOutOfBoundsException: 3
at
java.util.concurrent.ConcurrentHashMap$HashIterator.advance(ConcurrentHashMap.java:1086)
at
java.util.concurrent.ConcurrentHashMap$HashIterator.nextEntry(ConcurrentHashMap.java:1101)
at
java.util.concurrent.ConcurrentHashMap$KeyIterator.next(ConcurrentHashMap.java:1117)/
it fails here(ConcurrentHashMap implementation fragment):
/final void advance() {
if (nextEntry != null && (nextEntry = nextEntry.next) != null)
return;
while (nextTableIndex >= 0) {
if ( (nextEntry = currentTable[nextTableIndex--]) != null)
return;
}
while (nextSegmentIndex >= 0) {
Segment<K,V> seg = segments[nextSegmentIndex--];
if (seg.count != 0) {
currentTable = seg.table;
for (int j = currentTable.length - 1; j >= 0; --j) {
if ( (nextEntry = currentTable[j]) != null)
{*<-- failure*
nextTableIndex = j - 1;
return;
}
}
}
}
}/
JVM info:
/java version "1.6.0_30"
Java(TM) SE Runtime Environment (build 1.6.0_30-b12)
Java HotSpot(TM) Server VM (build 20.5-b03, mixed mode)/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20120216/0d514eb0/attachment-0001.html>
More information about the Concurrency-interest
mailing list