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判断就可 ...
随机推荐
- OA公文流转系统(未完成)
基本页面比较多,所以就不贴出来了,具体的页面可以自行浏览. 点我进入OA系统浏览界面(未做响应式布局,需电脑端打开) 账号密码: 部门:bumen------bumen 办公室:bangongshi- ...
- 谷歌SameSite策略
当我新下载谷歌80.x版本的时候,访问一个系统(内嵌跳转到其他系统的iframe),跳转过去没有携带cookie,以前版本的谷歌浏览器是可以的,控制台提示SameSite策略,给阻止了cookie携带 ...
- STL——容器(deque)deque 的删除 clear() erase()
deque.clear(); //移除容器的所有数据 1 #include <iostream> 2 #include <deque> 3 4 using namespace ...
- 冬季里有温度的 3D 可视化智慧供热系统
前言 随着供暖季来临,我国北方大部分省市开始陆续供热.一年一度的供暖问题被提上了日程.在我们的印象里,供热的设施不论是锅炉.管道还是暖气片,都是坚硬的钢铁.铸铁.HT 通过自主研发的强大的基于 HTM ...
- go并发之goroutine和channel,并发控制入门篇
并发的概念及其重要性 这段是简单科普,大佬可以跳过 并发:并发程序指同时进行多个任务的程序.在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行 ...
- 用 Roslyn 做个 JIT 的 AOP
0. 前言 上接:AOP有几种实现方式 接下来说说怎么做AOP的demo,先用csharp 说下动态编织和静态编织,有时间再说点java的对应内容. 第一篇先说Roslyn 怎么做个JIT的AOP d ...
- Java各版本新增特性, Since Java 8
Java各版本新增特性, Since Java 8 作者:Grey 原文地址: Github 语雀 博客园 Java 8 Reactor of Java 这一章来自于<Spring in Act ...
- Docker(二):Docker镜像仓库Harbor搭建
安装docker-compose 因为docker-compose下载容易失败, 所以选择从github下载方式安装. [root@harbor ~]# mv docker-compose-Linux ...
- Linux命令-1.远程登录
原网站:http://www.runoob.com/linux/linux-remote-login.html Linux一般作为服务器使用,而服务器一般放在机房,你不可能在机房操作你的Linux服务 ...
- 移动端 canvas基础1
一.canvas画布 Canvas是HTML5中新出的一个元素,开发者可以通过JS脚本动态绘制图像. #1. 创建canvas画布 在页面中创建canvas标签,并设置其id和宽高 (不要通过css设 ...