I loop over a list of sensor objects and drop the ones that have timed out: for (Sensor s : sensors) { if (s.isStale()) sensors.remove(s); }. This throws java.util.ConcurrentModificationException, although the program has only one thread. Even stranger, when the stale sensor happens to be the second-to-last element, no exception is thrown and the last element is silently skipped.
What does "concurrent" mean here if no other thread is involved, why is the behaviour inconsistent, and what is the right way to remove elements while iterating?




