ArrayList的ConcurrentModificationException异常和多线程下的异常
一、ConcurrentModificationException
ArrayList源码看为什么出现异常:
public class ArrayList<e> extends AbstractList<e>
implements Cloneable, Serializable, RandomAccess { @Override public boolean remove(Object object) {
Object[] a = array;
int s = size;
if (object != null) {
for (int i = 0; i < s; i++) {
if (object.equals(a[i])) {
System.arraycopy(a, i + 1, a, i, --s - i);
a[s] = null; // Prevent memory leak
size = s;
modCount++; // 只要删除成功都是累加
return true;
}
}
} else {
for (int i = 0; i < s; i++) {
if (a[i] == null) {
System.arraycopy(a, i + 1, a, i, --s - i);
a[s] = null; // Prevent memory leak
size = s;
modCount++; // 只要删除成功都是累加
return true;
}
}
}
return false;
} @Override public Iterator<e> iterator() {
return new ArrayListIterator();
} private class ArrayListIterator implements Iterator<e> {
...... // 全局修改总数保存到当前类中
/** The expected modCount value */
private int expectedModCount = modCount; @SuppressWarnings("unchecked") public E next() {
ArrayList<e> ourList = ArrayList.this;
int rem = remaining;
// 如果创建时的值不相同,抛出异常,
if (ourList.modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
if (rem == 0) {
throw new NoSuchElementException();
}
remaining = rem - 1;
return (E) ourList.array[removalIndex = ourList.size - rem];
} ......
}
}
由上可知,如果遍历中作get,remove操作都会改变modCount的值,但是此时expectedModCount还是保存以前的modCount的值,肯定不相等,抛出异常。
二、多线程下的异常
1、发生 ArrayIndexOutOfBoundsException 异常;
问题是出现在多线程并发访问下,由于没有同步锁的保护,造成了 ArrayList 扩容不一致的问题。
2、程序正常运行,输出了少于实际容量的大小;
这个也是多线程并发赋值时,对同一个数组索引位置进行了赋值,所以出现少于预期大小的情况。
3、程序正常运行,输出了预期容量的大小;
这是正常运行结果,未发生多线程安全问题,但这是不确定性的,不是每次都会达到正常预期的。
三、线程安全的CopyOnWriteArrayList
Java并发集合(一)-CopyOnWriteArrayList分析与使用
ArrayList的ConcurrentModificationException异常和多线程下的异常的更多相关文章
- Effective Java 第三版——69. 仅在发生异常的条件下使用异常
Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...
- 01 语言基础+高级:1-7 异常与多线程_day05 【异常、线程】
day05 [异常.线程] 主要内容 异常.线程 教学目标 能够辨别程序中异常和错误的区别 说出异常的分类 说出虚拟机处理异常的方式 列举出常见的三个运行期异常 能够使用try...catch关键字处 ...
- Java异常(一)Java异常简介及其框架
Java异常(一)Java异常简介及其框架 概要 本章对Java中的异常进行介绍.内容包括:Java异常简介Java异常框架 Java异常简介 Java异常是Java提供的一种识别及响应错误的一致性机 ...
- Java进阶专题(十五) 从电商系统角度研究多线程(下)
前言 本章节继上章节继续梳理:线程相关的基础理论和工具.多线程程序下的性能调优和电商场景下多线程的使用. 多线程J·U·C ThreadLocal 概念 ThreadLocal类并不是用来解决 ...
- javaSE高级篇1 — 异常与多线程基础
1.异常的体系结构 注:Throwable是一个类,不是一个接口,这个类里面是描述的一些Error和Exception的共性,如图所示: 异常 / 错误是什么意思? 定义:指的是程序运行过程中,可能 ...
- Vector 是线程安全的,是不是在多线程下操作Vector就可以不用加Synchronized
如标题一样,如果之前让我回答,我会说,是的,在多线程的环境下操作Vector,不需要加Synchronized. 但是我今天无意间看到一篇文章,我才发现我之前的想法是错误的,这篇文章的地址: http ...
- JavaSE复习(三)异常与多线程
异常 分类 编译时期异常:checked异常. 在编译时期,就会检查,如果没有处理异常,则编译失败.(如日期格式化异常) 运行时期异常:runtime异常. 在运行时期,检查异常.在编译时期,运行异常 ...
- ASP.NET MVC Filters 4种默认过滤器的使用【附示例】 数据库常见死锁原因及处理 .NET源码中的链表 多线程下C#如何保证线程安全? .net实现支付宝在线支付 彻头彻尾理解单例模式与多线程 App.Config详解及读写操作 判断客户端是iOS还是Android,判断是不是在微信浏览器打开
ASP.NET MVC Filters 4种默认过滤器的使用[附示例] 过滤器(Filters)的出现使得我们可以在ASP.NET MVC程序里更好的控制浏览器请求过来的URL,不是每个请求都会响 ...
- java线程基础巩固---多线程下的生产者消费者模型,以及详细介绍notifyAll方法
在上一次[http://www.cnblogs.com/webor2006/p/8419565.html]中演示了多Product多Consumer假死的情况,这次解决假死的情况来实现一个真正的多线程 ...
随机推荐
- 取消win10 任务栏已固定的软件
通过组策略编辑器 设置为“已禁用”,就可 ,自由取消已固定的图标.
- Javascript面向对象编程(一)
什么是面向对象? 它是一种新的编程模式.以往的面向过程是将功能都写在一起,逐行实现.面向对象与其不同,它只关心对象提供的功能,而不在乎细节. 面向对象的特点? 抽象:抓住问题的核心,贯穿始终: 封装: ...
- MM-物料分类帐差异分摊
物料分类帐差异分摊-MR21-MR22: https://wenku.baidu.com/view/6599e8f326fff705cc170ad8.html
- maven source 1.3 中不支持泛型 解决办法
maven打包时始终出现以下提示:1.-source 1.3 中不支持泛型(请使用 -source 5 或更高版本以启用泛型)List<User> userList= new ArrayL ...
- 二.第一个自动化demo,打开APP-如何获取包名和activity。(真机)
环境配置成功后,我们就可以进行第一个自动化测试了.用真机则不需要安装安卓模拟器.以一个简单的打开APP为例. 一.获取包名和activtity 启动一个app,我们需要知道它的平台.版本号. ...
- java将错误信息写入文件
第一种办法可以通过字符串,也就是先把错误信息写入字符串,再将字符串写入文件 import java.io.*; public class Demo { public static void main( ...
- Oracle :多表更新多个字段
https://blog.csdn.net/funnyfu0101/article/details/52765235 总体原则:1)更新的时候一定要加where条件,否则必然引起该字段的所有记录更新 ...
- 前端笔记-jquery
一.什么是jquery 1.jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team 2.jQuery是继prototype之后又一个优秀的 ...
- 【C++】纯C++实现http打开网页下载内容的功能
#include "stdafx.h" #include <windows.h> #include <iostream> #include "Wi ...
- C/C++控制台接收不到鼠标消息-【解决办法】
控制台编程中,使用了鼠标操作,遇到了控制台无法接收到鼠标消息的问题,可尝试一下办法解决 [win10系统] 在控制台标题栏右键-默认值-选项,将一下对勾取消 然后调用如下函数: HANDLE hIn ...