List<String> list = new ArrayList<String>();
list.add("a");
...
list.add("z");
synchronized(list) {
Iterator<String> i = list.iterator();
while(i.hasNext()) {
...
}
}
and
List<String> list = new ArrayList<String>();
list.add("a");
...
list.add("z");
List<String> synchronizedList = Collections.synchronizedList(list);
synchronized(synchronizedList) {
Iterator<String> i = synchronizedList.iterator();
while(i.hasNext()) {
...
}
}
Specifically, I’m not clear as to why synchronized is required in the second instance when a synchronized list provides thread-safe access to the list.
If you don’t lock around the iteration, you will get a ConcurrentModificationException if another thread modifies it during the loop.
Synchronizing all of the methods doesn’t prevent that in the slightest.
This (and many other things) is why
Collections.synchronized*is completely useless.You should use the classes in
java.util.concurrent. (and you should think carefully about how you will guarantee you will be safe)As a general rule of thumb:
For much more information, see my blog