我們先來(lái)看一段簡(jiǎn)單的代碼:
public class VectorFor {
public static void test1(Vector<Integer> vector){
for (Integer i: vector) {
if(i.equals(3)){
vector.remove(i);
}
}
}
public static void main(String[] args) {
Vector<Integer> vector=new Vector();
vector.add(1);
vector.add(2);
vector.add(3);
test1(vector);
}
}
看上去沒(méi)什么不妥罕袋,就是遍歷刪除指定元素嘛,運(yùn)行呢碍岔?
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.Vector$Itr.checkForComodification(Vector.java:1184)
at java.util.Vector$Itr.next(Vector.java:1137)
at com.example.demo.plaintest.VectorFor.test1(VectorFor.java:7)
at com.example.demo.plaintest.VectorFor.main(VectorFor.java:18)
Process finished with exit code 1
拋出了一個(gè)ConcurrentModificationException
異常
哪里拋出來(lái)的呢浴讯?
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
哪里調(diào)的這個(gè)方法呢?
public E next() {
synchronized (Vector.this) {
checkForComodification();
int i = cursor;
if (i >= elementCount)
throw new NoSuchElementException();
cursor = i + 1;
return elementData(lastRet = i);
}
}
那么表面原因很簡(jiǎn)單蔼啦,就是modCount != expectedModCount
,這里foreach循環(huán)其實(shí)還是用的迭代器榆纽,我這里調(diào)用的remove方法,這個(gè)方法里肯定有修改modcount
的地方,去看看
public synchronized boolean removeElement(Object obj) {
modCount++;
int i = indexOf(obj);
if (i >= 0) {
removeElementAt(i);
return true;
}
return false;
}
一直追蹤下去都沒(méi)有看見(jiàn)更新expectedModCount
的操作捏肢,所以呢到后面check的時(shí)候就指定會(huì)報(bào)錯(cuò)了
那么為什么會(huì)有它呢奈籽?參考了一下別的文章給出了解釋
這個(gè)和多線程并發(fā)修改相關(guān),先介紹一下fail-fast
機(jī)制:
“快速失敗”也就是fail-fast鸵赫,它是Java集合的一種錯(cuò)誤檢測(cè)機(jī)制衣屏。當(dāng)多個(gè)線程對(duì)集合進(jìn)行結(jié)構(gòu)上的改變的操作時(shí),有可能會(huì)產(chǎn)生fail-fast機(jī)制辩棒。記住是有可能狼忱,而不是一定。例如:假設(shè)存在兩個(gè)線程(線程1一睁、線程2)钻弄,線程1通過(guò)Iterator在遍歷集合A中的元素,在某個(gè)時(shí)候線程2修改了集合A的結(jié)構(gòu)(是結(jié)構(gòu)上面的修改者吁,而不是簡(jiǎn)單的修改集合元素的內(nèi)容)窘俺,那么這個(gè)時(shí)候程序就會(huì)拋出 ConcurrentModificationException 異常,從而產(chǎn)生fail-fast機(jī)制复凳。
之所以有modCount這個(gè)成員變量瘤泪,就是為了辨別多線程修改集合時(shí)出現(xiàn)的錯(cuò)誤。
在單線程的環(huán)境下也可能會(huì)發(fā)生該異常