李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
集合类不安全之并发修改异常
Leefs
2020-02-22 PM
2080℃
0条
# 集合类不安全之并发修改异常 **ArrayList并发修改异常代码** ```java import java.util.ArrayList; import java.util.List; import java.util.UUID; public class ContainerNotSafeDemo { public static void main(String[] args) { List
list = new ArrayList<>(); for(int i=1;i<=50;i++){ new Thread(()->{ list.add(UUID.randomUUID().toString().substring(0,8)); System.out.println(list); },String.valueOf(i)).start(); } } } ``` **运行控制台报错** ```java java.util.ConcurrentModificationException ``` `java.util.ConcurrentModificationException:`并发修改异常,做过并发类项目对于这个异常会很常见。 并发修改异常产生原因:一个线程正在进行写操作,另一个线程过来争抢线程执行权,导致线程写的过程被其他线程打断,导致数据不一致。 **解决方案** > 第一种:使用`List
arrayList = new Vector<>();`它的底层使用了synchronized加锁,但是并发下降 > > 第二种:使用`List
arrayList = Collections.synchronizedList(new ArrayList
());`使用工具类,保证线程同步 > > 第三种:使用`List
arrayList = new CopyOnWriteArrayList<>();`写时复制 **写时复制解析** CopyOnWrite容器即写时复制的容器。往一个容器中添加元素的时候,不直接往当前容器Object[]添加,而是先将当前容器Object[]进行Copy,复制出一个新的容器Object[] newElements,然后新的容器Object[] newElements里添加容器,添加完元素之后,再将容器的应用指向新的容器setArray(newElements);这样做的好处是可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素,所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。 **源码分析** ```java /** * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return {@code true} (as specified by {@link Collection#add}) */ public boolean add(E e) { final ReentrantLock lock = this.lock; //显示获取锁 lock.lock(); try { //通过getArray()方法获取容器Object[] Object[] elements = getArray(); //计算容器中元素的长度 int len = elements.length; //将当前容器Object[]进行Copy,复制出一个新的容器Object[],容器大小加1 Object[] newElements = Arrays.copyOf(elements, len + 1); //添加元素 newElements[len] = e; setArray(newElements); return true; } finally { //显示释放锁 lock.unlock(); } } ``` **附完整代码** ```java import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; public class ContainerNotSafeDemo { public static void main(String[] args) { //List
list = new ArrayList<>(); //List
list = new Vector<>(); //List
list = Collections.synchronizedList(new ArrayList
()); List
list = new CopyOnWriteArrayList<>(); for(int i=1;i<=50;i++){ new Thread(()->{ list.add(UUID.randomUUID().toString().substring(0,8)); System.out.println(list); },String.valueOf(i)).start(); } } } ```
标签:
Java
,
并发编程
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/639.html
上一篇
CAS的ABA问题及解决
下一篇
Java锁--读写锁简介
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
Zookeeper
NIO
散列
Yarn
JavaWEB项目搭建
GET和POST
正则表达式
工具
序列化和反序列化
HDFS
哈希表
FastDFS
递归
队列
MyBatisX
Spark RDD
机器学习
gorm
国产数据库改造
nginx
二叉树
Flink
Thymeleaf
Python
SQL练习题
Hbase
Tomcat
Linux
ClickHouse
FileBeat
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭