I'm occasionally getting a ConcurrentModificationException
when I iterate over a list. A Google search informs me that it's probably because I'm altering that list in another thread while iterating over it and that to make this problem go away I should use java.util.concurrent.CopyOnWriteArrayList
....
... except I already am.
Apparently, I'm doing something really stupid somewhere.
Does anybody have any insight into how one might induce CopyOnWriteArrayList
to toss a ConcurrentModificationException
? If it matters, I'm using Java 5.
Edit: Since the mutators I'm using may matter, I'm modifying this list in two ways:
- Adding elements to the front. (
list.add(0, newElement);
) - Using subList to let older items fall off the back. (
list = list.subList(0, MAX_LIST_SIZE);
)
Do those raise red flags? If so, why? My understanding was that because these operations make a copy of the thing first, any existing iterators would be pointing at the unmodified original and would thus not care. Do I have a hole in my knowledge?
Edit 2: The precise code that's causing the problem is still a bit murky, but I can at least post the exception I'm seeing:
java.util.ConcurrentModificationException
at java.util.concurrent.CopyOnWriteArrayList$COWSubList.checkForComodification(Unknown Source)
at java.util.concurrent.CopyOnWriteArrayList$COWSubList.iterator(Unknown Source)
at....
... where it points to a for-each loop instantiation in my code.
That COWSubList
does seem to imply that my call to subList
is the root of my problem; I'd still like to understand why.
Edit 3: *facepalm*
CopyOnWriteArrayList.subList()
returns a List
, not a CopyOnWriteArrayList
. The list it returns is under no implied obligation to provide any of COWAL's protections. Which makes using subList()
like this to remove elements a Very Bad Idea.
Don't know for certain if this is my culprit, but it's damned suspicious and needs to be corrected regardless.