I have just found HiddenInterator example, in the Java concurrency in practice book.
class ConcurentIterator implements Runnable {
// because of final it is immutable, so it is thread safe
private final Set<Integer> v = new HashSet<Integer>();
//private final Vector<Integer> v = new Vector<Integer>();
public synchronized void add(Integer i) {
v.add(i);
}
public synchronized void remove(Integer i) {
v.remove(i);
}
public void addTenThings() {
Random r = new Random();
for (int i = 0; i < 10; i++) {
add(r.nextInt());
System.out.println("DEBUG: added ten elements to " + v);
}
}
public void run() {
addTenThings();
}
}
I understand everything! that's nice!
I have the following question:
In java we have concurrent collections for instance: ConcurentSkipListMap, ConcurrentHashMap, where the problem is fixed. But I'm interested which are the classes where the problem can happen(where it is not fixed)? For instance can it be occur on vector? When I was testing, I can't throw the ConcurentModificationException in the vector.
Testing method:
public static void main(String[] args) {
Thread[] threadArray = new Thread[200];
ConcurentIterator in = new ConcurentIterator();
for (int i = 0; i < 100; i++) {
threadArray[i] = new Thread(in);
}
for (int i = 0; i < threadArray.length; i++) {
threadArray[i].start();
}
}
Thread unsafe collection will exhibit this behavior of throwing ConcurrentModificationException - examples are Arraylist, HashSet, HashMap, TreeMap, LinkedList...
Thread safe collections like vector will also exhibit this behavior if the collection is altered while it is being iterated without using the iterator in use.
What's your objective here - to know the name of all collections that can throw this exception; it is best if we focus on the concept and take individual examples to demonstrate the concept.
Adding an example below for the code that uses Vector and would still throw ConcurrentModificationException - the idea is that removals should be done via iterator or else the collection will fail signalling a concurrent attempt at modifying the collection
public static void main(String[] args) {
Vector<Integer> numbers = new Vector<Integer>(Arrays.asList(new Integer[]{1,2,3,4,5,6}));
for (Integer integer : numbers) {
System.out.println(integer);
numbers.remove(2);
}
}