1

I'm having some issues with a piece of java code which keeps triggering a ConcurrentModificationException. I can't really figure out what is going on, this is a fairly simple static class, not sure why it would be throwing this exception as everything is synchronized. This piece of code has been heavily used for several years, so it's odd that it would start having issues at this point:

java.util.ConcurrentModificationException
        at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:953)
        at java.util.LinkedList$ListItr.next(LinkedList.java:886)
        at DataSubscriptionManager.sendMessages(DataSubscriptionManager.java:18)


private static HashMap<DataClass,LinkedList<DataSubscriber>> subscriberMap = new HashMap();

 public static void sendMessages(LinkedList messages, DataClass dataClass) {
  synchronized (subscriberMap) {
   LinkedList<DataSubscriber> subscribers = subscriberMap.get(dataClass);
   if (subscribers != null) {
    for (DataSubscriber sub: subscribers) { *** EXCEPTION HAPPENS HERE***
     if (sub != null) {
      sub.sendMessages(messages);
     }
    }
   }
  }
 }


 public static void addDataSubscriber(DataSubscriber sub, DataClass dataClass) {
  synchronized (subscriberMap) {
   LinkedList<DataSubscriber> subscribers = subscriberMap.get(dataClass);
   if (subscribers == null) {
    subscribers = new LinkedList();
    subscriberMap.put(dataClass,subscribers);
   }
   while (subscribers.remove(sub)) {}
   subscribers.add(sub);
  }
 }

 public static void removeDataSubscriber(DataSubscriber sub, DataClass dataClass) {
  synchronized (subscriberMap) {
   LinkedList<DataSubscriber> subscribers = subscriberMap.get(dataClass);

   subscribers.remove(sub);
  }
 }
  • Can you add a stacktrace – mavarazy Jun 06 '14 at 15:52
  • 1
    Are these all the methods on this class? Are you sure you aren't leaking the instances of `LinkedList` out to some other class that isn't synchronising on the map? – andersschuller Jun 06 '14 at 15:53
  • Can it be, that someone is modifying messages list, while DataSubscriptionManager processes it? You have 2 LinkedList here, while the List of DataSubscribers seems to be safe, list of messages might change. – mavarazy Jun 06 '14 at 15:56
  • What happened was that the subscriber had code which removed itself from the subscription list when it detected that the connection had dropped, so it was calling removeDataSubscriber, causing the exception. But for some reason java only starts the stack trace from the outer lock vs the inner which makes it confusing to debug. – user3715654 Jan 12 '15 at 23:24
  • Possible duplicate of [ConcurrentModificationException despite using synchronized](http://stackoverflow.com/questions/1655362/concurrentmodificationexception-despite-using-synchronized) – Raedwald Jan 22 '16 at 16:05
  • 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

2 Answers2

2

What's happening is that your collection is being modified while you are iterating over it.

It's could be another thread, or it's possible one of your subscribers is either unsubscribing, or subscribing to a different dataClass in response to the message it receives.

Clive Evans
  • 658
  • 8
  • 12
0

You can try using Collections.synchronizedList(subscribers) which may help avoiding this problem.

Faizal
  • 33
  • 5