Java 的快速失败和平安失败

发布日期:2019-07-23 19:56:03 阅读数: 112次 来源: 作者:

一、快速失败(fail—fast)

在用迭代器遍历一个调集对象时,若是遍历过程中对调集对象的内容进行了点窜(添加、删除、点窜),则会抛出 Concurrent Modification Exception。

道理:迭代器在遍历时间接拜候调集中的内容,而且在遍历过程中利用一个 modCount 变量。调集在被遍历期间若是内容发生变化,就会改变 modCount 的值。每当迭代器利用 hashNext()/next() 遍历下一个元素之前,城市检测 modCount 变量能否为 expectedmodCount 值,是的话就前往遍历;不然抛出非常,终止遍历。

留意:这里非常的抛出前提是检测到 modCount != expectedmodCount 这个前提。若是调集发生变化时点窜 modCount 值刚好又设置为了 expectedmodCount 值,则非常不会抛出。因而,不克不及依赖于这个非常能否抛出而进行并发操作的编程,这个非常只建议用于检测并发点窜的 bug。

场景:java.util 包下的调集类都是快速失败的,不克不及在多线程下发生并发点窜(迭代过程中被点窜)。

二、平安失败(fail—safe)

采用平安失败机制的调集容器,在遍历时不是间接在调集内容上拜候的,而是先复制原有调集内容,在拷贝的调集长进行遍历。

道理:因为迭代时是对原调集的拷贝进行遍历,所以在遍历过程中对原调集所作的点窜并不克不及被迭代器检测到,所以不会触发 Concurrent Modification Exception。

错误谬误:基于拷贝内容的长处是避免了 Concurrent Modification Exception,但同样地,迭代器并不克不及拜候到亚博手机app点窜后的内容,即:迭代器遍历的是起头遍历那一刻拿到的调集拷贝,在遍历期间原调集发生的点窜迭代器是不晓得的。

场景:java.util.concurrent 包下的容器都是平安失败,能够在多线程下并发利用,并发点窜。

本文由亚博编辑整理亚博手机app