1.迭代都不会抛出ConcurrentModificationException
synchronized的同步容器, 迭代时,需要对整个列表对象加锁,否则会抛ConcurrentModificationException
Collections .synchronizedList(new ArrayList<>())
和CopyOnWriteArrayList
为例
public class IteratorProblemDemo {
private static void startModifyThread(final List<String> list) {
Thread modifyThread = new Thread(() -> {
for (int i = 0; i < 100; i++) {
list.add("item " + i);
try {
Thread.sleep((int) (Math.random() * 10));
} catch (InterruptedException e) {
}
}
});
modifyThread.start();
}
private static void startIteratorThread(final List<String> list) {
Thread iteratorThread = new Thread(() -> {
while (true) {
//synchronized的同步容器,这里会抛出ConcurrentModificationException
for (String str : list) {
//do something
System.out.println(str);
}
}
});
iteratorThread.start();
}
public static void main(String[] args) {
final List<String> list = Collections .synchronizedList(new ArrayList<>());
startIteratorThread(list);
startModifyThread(list);
}
}
但是,CopyOnWriteArrayList 能正常运行
public static void main(String[] args) {
List<String> list = new CopyOnWriteArrayList<>();
startIteratorThread(list);
startModifyThread(list);
}
2. 支持一些原子复合操作
3.迭代中的弱一致性
在迭代过程中,如果另一个线程对容器进行了修改,迭代会继续,不会抛出异常(读写并行)。迭代的也不是副本
如果变化发生在已遍历过的部分,迭代器就不会反映出来,而如果变化发生在未遍历过的部分,迭代器就会发现并反映出来
所有有时候修改能被看到,有时候看不到