The following code triggers a ConcurrentModificationException very, very quickly:
import java.util.*;
public class SynchFail {
static List<Integer> LIST = new ArrayList<Integer>();
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
LIST.add(1);
}
}}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
List<Integer> syncList = Collections.synchronizedList(LIST);
synchronized(syncList) {
for (Integer thisInt : syncList) {
}
}
}
}}).start();
}
}
... whereas the following behaves as it should:
import java.util.*;
public class SynchSucceed {
static List<Integer> LIST = new ArrayList<Integer>();
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
synchronized(LIST) {
LIST.add(1);
}
}
}}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
synchronized(LIST) {
for (Integer thisInt : LIST) {
}
}
}
}}).start();
}
}
... my understanding was that synchronized collections were to prevent ConcurrentModificationException
s in situations like this (but clearly they do not).
Given this: where should I make use of these ?