The java.util Collection classes are fail-fast, which means that if one thread changes a collection while another thread is traversing it through with an iterator the iterator.hasNext() or iterator.next() call will throw ConcurrentModificationException. Even the synchronized collection wrapper classes SynchronizedMap and SynchronizedList are only conditionally thread-safe, which means all individual operations are thread-safe but compound operations where flow of control depends on the results of previous operations may be subject to threading issues.
Problem: Review the code below which may throw a ConcurrentModificationException and propose solutions to fix the issue.
Collection<String> myStr = new ArrayList<String>(10);
for (Iterator it = myStr.iterator(); it.hasNext();)
String myObject = (String)it.next();
if (1 == 1) // some condition
myStr.remove(myObject); //can throw ConcurrentModificationException
Answer 1: The list can be converted to an array with list.toArray() and iterate on the array. This approach is not
recommended if the list is large.
Answer 2: The entire list can be locked while iterating by wrapping your code within a synchronized block. This approach adversely affects scalability of your application if it is highly concurrent.
Answer 3: JDK 1.5 gives you ConcurrentHashMap and CopyOnWriteArrayList classes, which provide much better scalability and the iterator returned by ConcurrentHashMap.iterator() will not throw ConcurrentModificationException while preserving thread-safety.
Answer 4: Remove the current object via the Iterator “it” which has a reference to the underlying collection “myStr”. The Iterator object provides it.remove() method for this purpose.