什么是快速失败机制
1.7的jdk这么写到
if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove
method, the iterator will throw a ConcurrentModificationException
. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.
Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException
on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.
大概意思是:如果map在迭代的时候被修改了结构,除了使用迭代器本身的remove方法之外,否则就会扔出一个异常.因此面对并发的场景下map的迭代很快就会抛出异常.
fail-fast的表现不是能够保证一定发生,只是尽最大努力抛出异常.因此编写依赖于此异常的程序的做法是错误的.
Map,ArrayList等集合类都实现了这个机制
下面使用代码来实现一下这个机制
public class FailFastTest {
private static List<Integer> list = new ArrayList<>();
private static class ThreadOne extends Thread {
public void run() {
Iterator<Integer> integerIterator = list.iterator();
while (integerIterator.hasNext()) {
int i = integerIterator.next();
System.out.println("Thread one run :" + i);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private static class ThreadTwo extends Thread {
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Thread Two run:" + i);
if (i == 3) {
list.remove(3);
}
}
}
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
list.add(i);
}
new ThreadOne().start();
new ThreadTwo().start();
}
}
输出异常
Exception in thread "Thread-0" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at com.sample.map.failfast.FailFastTest$ThreadOne.run(FailFastTest.java:16)
遍历的过程中,另一个线程修改了这个ArrayList的结构.导致抛出异常,不再继续向下执行.
网友评论