当前位置:网站首页>The difference between quick failure and safe failure
The difference between quick failure and safe failure
2022-06-22 03:37:00 【Healthy brick carrier】
stay java.util Package collection classes are all fast failure ; and java.util.concurrent The classes under the package are all security failures
Fast failure :
In iterating over a collection using an iterator , If A The thread is traversing the collection , here B Thread modifies the collection ( increase 、 Delete 、 modify ), perhaps A The thread modifies the collection during traversal , Will result in A Thread throws ConcurrentModificationException abnormal .
Here we have ArrayList Part of the source code as an example ,JDK Version is 1.8.
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
protected transient int modCount = 0;
}
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
public void clear() {
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
// Iterator Interface
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
Itr() {
}
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
}
You can see ArrayList Of set()、clear() And other operations will make modCount Variable change ,modCount Indicates the number of changes
and ArrayList Inner class Itr Realized Iterator Interface , Whenever the iterator uses hashNext()/next() Before traversing the next element , Metropolitan detection modCount Is the variable expectedModCount value , Yes, return to traversal ; Otherwise, throw an exception , Termination traversal .
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
Examples of quick failures :
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("a1");
list.add("a2");
list.add("a3");
list.add("a4");
Iterator<String> it = list.iterator();
System.out.println("list1:"+list);
while (it.hasNext()){
String str = it.next(); // Raised here java.util.ConcurrentModificationException abnormal
if (str.equals("a3")){
list.add("a99");
}
}
System.out.println("list2:"+list);
}
Output :
Exception in thread "main" java.util.ConcurrentModificationException
list1:[a1, a2, a3, a4]
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at com.example.demo.Main.main(Main.java:96)
summary :
Iterators directly access the contents of the collection when traversing , And use a... In the traversal process modCount Variable ( Indicates the number of changes ). If the contents of the collection change during traversal , Will change modCount Value . Whenever the iterator uses hashNext()/next() Before traversing the next element , Metropolitan detection modCount Is the variable expectedModCount value ( During the initialization of the iterator modCount This value is assigned to the iterator expectedModCount), Yes, return to traversal ; Otherwise, throw an exception , Termination traversal .( If it is not equal, it means that other threads have been modified aggregate )
Security failure :
Collection container with security failure mechanism , Not directly accessed on the collection content when traversing , Instead, copy the contents of the original collection first , Traversing over the set of copies .
Because the iteration is to traverse the copy of the original set , Therefore, changes made to the original set during traversal cannot be detected by the iterator , So I can't throw ConcurrentModificationException abnormal
边栏推荐
- Wechat applet onpagescroll is invalid
- 倍福TwinCAT 3 气缸动作程序编写
- 倍福TwinCAT3中PLC程序变量定义和硬件IO关联
- 1690. stone game vii- dynamic programming method
- Nebula Graph学习篇2_版本v2.6.1之前的bug导致OOM
- Use yolov5 to train your own data set; Installation and use of yolov5; Interpretation of yolov5 source code
- cmd看控制台输出红桃、方块、黑桃、梅花乱码解决
- vim常用命令
- [qnx hypervisor 2.2 user manual]5.5 starting and using guest
- 八大排序之直接插入排序
猜你喜欢

ASUS reinstallation system keyboard lamp failure = & gt; Refitting the ATK drive
![[nvme2.0b 12] NVM capacity model](/img/e5/c898cb1eeeabce757a2b07b08f9219.png)
[nvme2.0b 12] NVM capacity model

Why is the first program a programmer writes "Hello world!"

MySQL index creation, optimization analysis and index optimization

基于51的超声波测距仪代码(截图版)

微信小程序聊天 表情

动态规划-使用最小花费爬楼梯为例

内网穿透

A component required a bean of type 'com. example. demo3.service. UserServiceImp' that could not be fou

Use yolov5 to train your own data set; Installation and use of yolov5; Interpretation of yolov5 source code
随机推荐
Rabbmitmq publish subscribe mode < 2 >
C # custom sorting
Scheduling function: Splunk operator Controller Manager
指针与指针的指针
cmd看控制台输出红桃、方块、黑桃、梅花乱码解决
Talk about the Flink waterline
3DE robot suction cup grabbing box
3DE position of moving object
MySQL index creation, optimization analysis and index optimization
H指数问题
我们如何解决了RealSense偏色问题?
2019年全国职业院校技能大赛中职组“网络空间安全”正式赛卷及其“答案”
std::make_ Shared features
Factory mode
告警日志中出现ORA-48132 ORA-48170
Rabbmitmq simple mode < 1 >
Sword finger offer 68 - I. nearest common ancestor of binary search tree
Atcoder beginer contest 252 (Dijkstra, reverse thinking)
When 618 attacks, how to choose between Beibei X3 and Jimi h3s? Take you all-round in-depth analysis
Shelling of ESP law of reverse crackme