java基础之ArrayList 和Vector、CopyOnWriteArrayList。 三者之间的区别: 1.我们都知道ArrayList 是线程不安全的,不存在同步。 2.像Vector这种,add、remove方法都是原子操作,不会被打断,但也仅限于此,如果有个线程在遍历某个Vector、有个线程同时在add这个Vector,99%的情况下都会出现ConcurrentModificationException,也就是fail-fast机制。 3.说到底CopyOnWriteArrayList 是最安全的,CopyOnWriteArrayList为什么能解决同步的问题呢?CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。CopyOnWriteArrayList中add/remove等写方法是需要加锁的,目的是为了避免Copy出N个副本出来,导致并发写。但是。CopyOnWriteArrayList中的读方法是没有加锁的。 我就在想Vector怎么样才能报错 报错,我们才能更深一层理解CopyOnWriteArrayList的强大。 有可能有朋友说ArrayList是非线程安全的容器,换成Vector就没问题了,实际上换成Vector还是会出现这种错误。 原因在于,虽然Vector的方法采用了synchronized进行了同步,但是实际上通过Iterator访问的情况下,每个线程里面返回的是不同的iterator,也即是说expectedModCount是每个线程私有。假若此时有2个线程,线程1在进行遍历,线程2在进行修改,那么很有可能导致线程2修改后导致Vector中的modCount自增了,线程2的expectedModCount也自增了,但是线程1的expectedModCount没有自增,此时线程1遍历时就会出现expectedModCount不等于modCount的情况了。 因此一般有2种解决办法: 1)在使用iterator迭代的时候使用synchronized或者Lock进行同步; 2)使用并发容器CopyOnWriteArrayList代替ArrayList和Vector。 参考https://www.cnblogs.com/dolphin0520/p/3933551.html
|