4

I'm facing some really strange problems while implementing a kind of Kademlia bucket in Java 8 (OpenJDK).

I need to get at least a specific number of items from so-called Buckets. But that's not the problem.

Somehow, I get sometimes a ConcurrentModificationException while doing closest.addAll() on the ArrayList though it is just used in a single thread and I'm not iterating or doing something like that.

Do you know how to help me? Here is my code (I know it's a mess!):

List<Neighbour> getClosest(Node n, int num) {
    ArrayList<Neighbour> closest = new ArrayList<>();
    int missing;
    int walkDown = n.getBucket(me);
    int walkUp = walkDown + 1;
    boolean pleaseBreak = true;
    while (true) {
        missing = num - closest.size();
        if (missing <= 0) {
            return closest;
        }

        if (walkUp >= 0 && walkUp < 160) {
            List<Neighbour> l = buckets[walkUp].getClosest(missing);
            closest.addAll(l);
            if (closest.size() >= missing) {
                return closest;
            }
            walkUp++;
            pleaseBreak = false;
        }

        if (walkDown >= 0 && walkDown < 160) {
            List<Neighbour> l = buckets[walkDown].getClosest(missing);
            closest.addAll(l);
            if (closest.size() >= missing) {
                return closest;
            }
            walkDown--;
            pleaseBreak = false;
        }

        if (pleaseBreak) {
            return closest;
        }
        pleaseBreak = true;
    }
}
Marcel
  • 245
  • 4
  • 9
  • What type is `buckets[walkDown]`? And can you show the code of `getClosest(missing)`? – Eran Jan 22 '15 at 11:53
  • this looks fine, please provide a [mcve](http://stackoverflow.com/help/mcve) – BeyelerStudios Jan 22 '15 at 11:57
  • Please post a stack trace. – Natix Jan 22 '15 at 11:57
  • 1
    Possible duplicate of [Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop](http://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re) – Raedwald Mar 28 '16 at 14:46

1 Answers1

4

ConcurrentModificationException actually means that you are breaking the rules of iteration by somehow modifying the list while iterating it.

Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.

That said it is fairly clear what could be causing this issue. As closest is a new List being filled by the method it must be l that is being modified.

There are two options:

  1. Another thread is doing it.
  2. You already have an iterator open across the list l.

Assuming it is not 1 (or you would probably have mentioned that) I will go for:

Your getClosest method is returning a sublist of a list that is being iterated across and/or modified and addAll is also attempting to iterate over it.

To fix, make getClosest return a copy of the sublist.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213