在Java中,同步容器主要包括2类:java
Collections.synchronizedCollection(Collection<T> c) Collections.synchronizedSet(Set<T> s) Collections.synchronizedList(List<T> list) Collections.synchronizedMap(Map<K,V> m)
同步容器的缺陷:数组
对Vector、ArrayList在迭代的时候若是同时对其进行修改就会抛出java.util.ConcurrentModificationException异常。即:安全
public class Test { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<Integer>(Arrays.asList(1,2)); Iterator<Integer> iterator = list.iterator(); while(iterator.hasNext()){ Integer integer = iterator.next(); if(integer == 2) list.remove(integer); } } }
结果抛出异常:java.util.ConcurrentModificationException多线程
一样并发
for(Integer i: list){ if(2 == i){ list.remove(i); } }
也会抛出异常。性能
可是有一点,java7下,要修改的元素不是list的最后一位则不会抛异常,不懂。线程
ArrayList<Integer> list = new ArrayList<Integer>(Arrays.asList(1,2,3)); Iterator<Integer> iterator = list.iterator(); while(iterator.hasNext()){ Integer integer = iterator.next(); if(integer == 2) list.remove(integer); }
上面这种状况不会抛出异常。code
// TODO 分析源码继承
缘由:调用list.remove()方法致使modCount和expectedModCount的值不一致。接口
(1)调用Iterator.remove()
public class Test { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<Integer>(Arrays.asList(1,2)); Iterator<Integer> iterator = list.iterator(); while(iterator.hasNext()){ Integer integer = iterator.next(); if(integer == 2) iterator.remove(); //注意这个地方 } } }
(2)额外使用list保存要删除的元素
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1,2)); Iterator<Integer> iterator = list.iterator(); ArrayList<Integer> toRemove = new ArrayList<>(); while (iterator.hasNext()){ Integer integer = iterator.next(); if(integer == 2){ toRemove.add(integer); } } list.removeAll(toRemove);
上述方法中的第一种,在多线程下并不适用。无论使用的是ArrayList仍是线程安全的Vector,均可能会抛出异常。
一般的两种解决办法: