fail-fast机制
快速失败模块的职责是检测错误,然后让系统的下一个最高级别处理错误。一旦发生异常, 直接停止并上报。尽最大努力去抛出异常。
这样做的好处是可以预先识别出一些错误情况,但是它同样也可能会为我们带来一些问题。
集合类的fail-fast机制
当多个线程对部分集合进行结构上的改变操作,有可能会产生fail-fast机制,这时候会抛出ConcurrentModificationException
使用增强for循环尝试删除集合中的元素会报这个异常
我们对class进行反编译,可以发现foreach其实是依赖了while循环和Iterator实现的
真正报错的原因是checkForComodification方法
它会检查modCount和expectedModCount的值是否相等。
modCount是ArrayList中的一个成员变量。它表示集合实际被修改的次数
expectedModCount是ArrayList的一个内部类Itr的成员变量 HashMap HashMapSpliterator的成员变量
然后使用remove方法 只会对modCount进行修改,所以在下一次next的时候就会报错
fail-fast 的主要目的就是识别并发,然后通过异常的方式通知用户
fail-safe机制
java.util.concurrent 包下的容器都是 fail-safe 的,可以在多线程下并发使用,并发 修改。同时也可以在 foreach 中进行 add/remove 。
fail-safe 集合的所有对集合的修改都是先拷贝一份副本,然后在副本集合上进行的, 并不是直接对原集合进行修改。并且这些修改方法,如 add/remove 都是通过加锁来控制并发的。
迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的。
Copy-On-Write 简称 COW,是一种用于程序设计中的优化策略。其基本思路是, 从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容 Copy 出去形成一个新的内容然后再改,这是一种延时懒惰策略。
CopyOnWrite 容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时 候,不直接往当前容器添加,而是先将当前容器进行 Copy,复制出一个新的容器,然后新 的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。
它的add/remove方法是需要加锁的,为了避免copy出n个副本出来,导致并发写
但是它的读方法是没有加锁的,这样做的好处是我们可以对 CopyOnWrite 容器进行并发的读,当然,这里读到的数据可能不是最新的。因为写时复制的思想是通过延时更新的策略来实现数据的最终一致性的,并非强一致性。
CopyOnWrite 并发容器用于读多写少的并发场景。比如白名单,黑名单,商品类目的 访问和更新场景。
本次文章的内容就到这里~