java - Unexpected ConcurrentModificationException -
not sure why i'm getting exception. issue onclose
called prior closeallopensessions
. onclose
operates normally, removing specified element _opensessions
. however, when closeallsessions
called concurrentmodificationexception
generated when attempt loop on _opensessions.
the exception not occur when comment out remove statement. considering how both these operations protected same mutex, unsure why happening. missing?
class b { protected void onclose(session session, list<websocketsessionstateful> opensessions) throws ioexception { iterator<websocketsessionstateful> opensessionselements = opensessions.iterator(); while(opensessionselements.hasnext()) { websocketsessionstateful opensession = opensessionselements.next(); if(session.equals(opensession.getsession())) { opensessionselements.remove(); // comment me out not throw exception return; } } } protected static void closeallopensessions(list<websocketsessionstateful> opensessions) throws ioexception { for(websocketsessionstateful opensession : opensessions) // exception generated here { opensession.getsession().close(new closereason(closereason.closecodes.going_away, "")); } } } class extends b { private static final object _endpointoperationmutex = new object(); private static final list<websocketsessionstateful> _opensessions = new arraylist<websocketsessionstateful>(); public void onclose(session session, endpointconfig config) throws ioexception { synchronized (_endpointoperationmutex) { super.onclose(session, _opensessions); } } static void closesessions() throws ioexception { synchronized (_endpointoperationmutex) { websocketendpointbase.closeallopensessions(_opensessions); } } }
in closeallopensesions()
method, you're iterating on opensessions
collection and, each element in it, calling close()
, of course causes onclose()
method fire. you're iterating on , removing opensessions
each call onclose()
method - concurrent modification coming from.
you can conceptualize problem more follows:
iterator outerloop = coll.iterator(); while (outerloop.hasnext) { iterator innerloop = coll.iterator(); while (innerloop.hasnext()){ innerloop.remove(); //concurrentmodificationexception } }
this no different than:
(object o : coll) (object p : coll) if (p.someboolean()) remove(p); //concurrentmodificationexception
you can't have 2 iterators iterating on the same collection simultaneously. if do, concurrentmodificationexception
thrown if inner loop removes element outer loop expecting iterate over.
at glance, don't see why need iterate on opensessions
within b.onclose()
. why should b.onclose()
responsible closing open sessions? shouldn't done in closeallopensessions()
?
Comments
Post a Comment