java集合并发操作异常解决方法:CopyOnWriteArrayList
一、我们知道ArrayList是线程不安全的,请编写一个不安全的案例并给出解决方案
HashSet与ArrayList一致 HashMap
HashSet底层是一个HashMap,存储的值放在HashMap的key里,value存储了一个PRESENT的静态Object对象
protected transient int modCount = 0; 记录集合操作次数的,这个变量如果不一致与期望的不一致,就会产生ConcurrentModificationException
1、线程不安全
package com.jian8.juc.collection; import java.util.ArrayList;
import java.util.List;
import java.util.UUID; /**
* 集合类不安全问题
* ArrayList
*/
public class ContainerNotSafeDemo {
public static void main(String[] args) {
notSafe();
} /**
* 故障现象
* java.util.ConcurrentModificationException
*/
public static void notSafe() {
List<String> list = new ArrayList<>();
for (int i = 1; i <= 30; i++) {
new Thread(() -> {
list.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(list);
}, "Thread " + i).start();
}
}
}
报错:
Exception in thread "Thread 10" java.util.ConcurrentModificationException
2、导致原因
并发正常修改导致
一个人正在写入,另一个同学来抢夺,导致数据不一致,并发修改异常
3、解决方法:**CopyOnWriteArrayList
List<String> list = new Vector<>();//Vector线程安全
List<String> list = Collections.synchronizedList(new ArrayList<>());//使用辅助类
List<String> list = new CopyOnWriteArrayList<>();//写时复制,读写分离
Map<String, String> map = new ConcurrentHashMap<>();
Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
CopyOnWriteArrayList.add方法:
CopyOnWrite容器即写时复制,往一个元素添加容器的时候,不直接往当前容器Object[]添加,而是先将当前容器Object[]进行copy,复制出一个新的容器Object[] newElements,让后新的容器添加元素,添加完元素之后,再将原容器的引用指向新的容器setArray(newElements),这样做可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素,所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
java集合并发操作异常解决方法:CopyOnWriteArrayList的更多相关文章
- ConcurrentModificationException 集合并发修改异常 解决
import java.util.ArrayList; import java.util.List; import java.util.ListIterator; /** * 问题? * 有一个集合, ...
- Tomcat部署java项目java.lang.OutOfMemoryError异常解决方法
java.lang.OutOfMemoryError异常解决方法 Window系统环境下,在catalina.bat文件第一行添加以下内容 set JAVA_OPTS=-Xms512m -Xmx512 ...
- Java 集合快速失败异常
快速失败 在JDK中,查看集合有很多关于快速失败的描述: 注意,此实现不是同步的.如果多个线程同时访问一个哈希映射,而其中至少一个线程从结构上修改了该映射,则它必须 保持外部同步.(结构上的修改是指添 ...
- Java最重要的21个技术点和知识点之JAVA集合框架、异常类、IO
(三)Java最重要的21个技术点和知识点之JAVA集合框架.异常类.IO 写这篇文章的目的是想总结一下自己这么多年JAVA培训的一些心得体会,主要是和一些java基础知识点相关的,所以也希望能分享 ...
- 转载:Java高并发,如何解决,什么方式解决
原文:https://www.cnblogs.com/lr393993507/p/5909804.html 对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并 ...
- 【转】Java高并发,如何解决,什么方式解决
原文地址:https://www.cnblogs.com/lr393993507/p/5909804.html 对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了. ...
- Android 异常解决方法【汇总】
(1)异常:Android中引入第三方Jar包的方法(Java.lang.NoClassDefFoundError解决办法) 1.在工程下新建lib文件夹,将需要的第三方包拷贝进来.2.将引用的第三方 ...
- java.net.SocketException: Connection reset 解决方法
java.net.SocketException: Connection reset 解决方法 最近纠结致死的一个java报错java.net.SocketException: Connection ...
- mybatis invalid comparison: java.sql.Timestamp and java.lang.String报错解决方法
这个错的意思是:java.sql.Timestamp和java.lang.String无效的比较 错误的原因是:拿传入的时间类型参数与空字符串进行比较就会报这个异常 解决方法:只保留非null判断就可 ...
随机推荐
- PyQt(Python+Qt)帮助文档官网及文档下载
一.帮助文档下载 老猿在网上找到一个Qt 5.9的帮助文档,没有找到最新版的,并且这个文档官网上没有下载,不知道源头在哪里可以下载. 文档存放在百度网盘: 链接:https://pan.baidu.c ...
- 派大星的烦恼MISC
挺有意思的杂项,python将二进制转图片的时候出现的图片不像二维码,想看题解的时候发现网上的大部分题解都是直接转发,更有意思了. 题目是派大星的烦恼,给了我们一张粉红图片,放进010editor里面 ...
- Leetcode学习笔记(1)
scrapy爬虫的学习告一段落,又因为现在在学习数据结构,做题平台是lettcode:https://leetcode-cn.com/ 每周都要交一次做题的笔记,所以把相关代码和思路同时放在博客上记录 ...
- datagrip2020最新安装破解教程方法激活码安装参数
现在,datagrip的版本已更新至2020.3,尚未升级的用户请赶快升级. 本文教您如何安装datagrip2020.3版本并破解它. 此方法可以100%永久激活datagrip2020.3(低版本 ...
- Java集合源码分析(五)——HashMap
简介 HashMap 是一个散列表,存储的内容是键值对映射. HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io.Serializable接口. HashM ...
- 关于Android手机CPU不同架构的问题
1.共有7种架构 armeabiv-v7a: 第7代及以上的 ARM 处理器.2011年15月以后的生产的大部分Android设备都使用它. arm64-v8a: 第8代.64位ARM处理器,很少设备 ...
- PluginOK中间件高级版-支持在Chrome、Edge、Firefox等浏览器网页中真正内嵌ActiveX等控件运行的版本已获多家上市公司采购
PluginOK(牛插)中间件(原名:本网通WebRunLocal)是一个实现WEB浏览器(Web Browser)与本地程序(Local Application)之间进行双向调用的低成本.强兼容.安 ...
- 【Go语言绘图】图片添加文字(一)
前一篇讲解了利用gg包来进行图片旋转的操作,这一篇我们来看看怎么在图片上添加文字. 绘制纯色背景 首先,我们先绘制一个纯白色的背景,作为添加文字的背景板. package main import &q ...
- PHP面向对象的学习(封装,继承,多态)
这个文章就是记录 巩固一下PHP的面向对象的部分 ,无非就是封装,继承,多态等等这几部分 这里参考了一位大佬总结的文章:https://www.cnblogs.com/adaia/p/6986576 ...
- redis 五种常见攻击方法
如果需要大佬写好的脚本,可以直接去github上面搜 参考文章:https://www.cnblogs.com/wineme/articles/11731612.html https://www ...