从源码级理解JAVA的并发修改异常
来源:互联网 发布:股票交易软件下载排名 编辑:程序博客网 时间:2024/06/04 18:33
首先先铺垫一下
在Itr初始化(用ArrayList内部方法new出来的public Iterator<E> iterator()),时int expectedModCount = modCount (此变量定义在java.util.AbstractList类中, 为已从结构上修改此列表的次数). modeCount初始值为0,但是ArrayList的方法: add(两个重载方法)都会调用方法 ensureCapacityInternal(size + 1); 会增加modCount的值; remove remove(int index) 会直接modCount++; remove(Object o) 会调用 fastRemove(int index) 使modCount++ 其他的更改集合长度的都会改变modCount值;
再看下面的代码:
我们在调用Itr(ArrayList的)的next方法时,第一行会检测checkForComodification();
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
如果我们在遍历时(或者forPlus++遍历集合)时修改了集合的长度,那么modCount的值发生改变,则
检测不会过,直接抛并发修改异常;
而ListItr为Itr的子类但每次add时虽然修改了集合长度,但及时expectedModCount = modCount;所以用迭代器的方法在遍历时(或者forPlus++遍历集合)修改集合长度不会并发修改异常
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; //初始值为0 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(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
private class ListItr extends Itr implements ListIterator<E> { ListItr(int index) { super(); cursor = index; } public boolean hasPrevious() { return cursor != 0; } public int nextIndex() { return cursor; } public int previousIndex() { return cursor - 1; } @SuppressWarnings("unchecked") public E previous() { checkForComodification(); int i = cursor - 1; if (i < 0) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i; return (E) elementData[lastRet = i]; } public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.set(lastRet, e); } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } public void add(E e) { checkForComodification(); try { int i = cursor; ArrayList.this.add(i, e); cursor = i + 1; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } }
0 0
- 从源码级理解JAVA的并发修改异常
- Java并发修改异常
- 理解和解决Java并发修改异常ConcurrentModificationException
- Java并发修改异常ConcurrentModificationException
- JAVA ConcurrentModificationException并发修改异常
- 迭代器的并发修改异常
- 深入分析集合并发修改异常(源码分析)java.util.ConcurrentModificationException
- 【Java源码分析】ConcurrentModificationException并发修改异常分析与解决方案(快速失败与安全失败)
- 从JDK源码角度看java并发的公平性
- 从JDK源码角度看java并发线程的中断
- java.util.ConcurrentModificationException:并发修改异常!
- java.util.ConcurrentModificationException 并发修改异常处理
- java迭代器并发修改异常说明
- 从源码理解TreeMap.java
- 从源码理解ArrayList.java
- 从源码理解LinkedHashMap.java
- 从源码理解LinkedList.java
- 从源码理解HashSet.java
- (3)Spring-boot学习 做一个简单的带访问数据库的web项目
- VS 2008 可扩展性开发(五):操作Solution、Project和ProjectItem
- 数据表的垂直分隔
- Nginx SSL+tomcat集群,request.getScheme() 取到https正确的协议
- IO流
- 从源码级理解JAVA的并发修改异常
- Android 4.4 Kitkat 使能 USB adb 功能
- VS 2008 可扩展性开发(六):操作Solution Explorer
- 如何添加或删除 ubuntu 用户和组
- std--remove_if
- 社内敬语的使用方法
- Golang 通关初级(2)
- 常用设计者模式---命令模式
- C#--Switch Case语句的返回