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;
    }
}
4

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I was such an idiot. Now, it's working fine, I'm just using a copy-constructor.
@Marcel - It's a common mistake. A copy constructor is a good solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.