一、我们知道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的更多相关文章

  1. ConcurrentModificationException 集合并发修改异常 解决

    import java.util.ArrayList; import java.util.List; import java.util.ListIterator; /** * 问题? * 有一个集合, ...

  2. Tomcat部署java项目java.lang.OutOfMemoryError异常解决方法

    java.lang.OutOfMemoryError异常解决方法 Window系统环境下,在catalina.bat文件第一行添加以下内容 set JAVA_OPTS=-Xms512m -Xmx512 ...

  3. Java 集合快速失败异常

    快速失败 在JDK中,查看集合有很多关于快速失败的描述: 注意,此实现不是同步的.如果多个线程同时访问一个哈希映射,而其中至少一个线程从结构上修改了该映射,则它必须 保持外部同步.(结构上的修改是指添 ...

  4. Java最重要的21个技术点和知识点之JAVA集合框架、异常类、IO

    (三)Java最重要的21个技术点和知识点之JAVA集合框架.异常类.IO  写这篇文章的目的是想总结一下自己这么多年JAVA培训的一些心得体会,主要是和一些java基础知识点相关的,所以也希望能分享 ...

  5. 转载:Java高并发,如何解决,什么方式解决

    原文:https://www.cnblogs.com/lr393993507/p/5909804.html 对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并 ...

  6. 【转】Java高并发,如何解决,什么方式解决

    原文地址:https://www.cnblogs.com/lr393993507/p/5909804.html 对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了. ...

  7. Android 异常解决方法【汇总】

    (1)异常:Android中引入第三方Jar包的方法(Java.lang.NoClassDefFoundError解决办法) 1.在工程下新建lib文件夹,将需要的第三方包拷贝进来.2.将引用的第三方 ...

  8. java.net.SocketException: Connection reset 解决方法

    java.net.SocketException: Connection reset 解决方法 最近纠结致死的一个java报错java.net.SocketException: Connection ...

  9. mybatis invalid comparison: java.sql.Timestamp and java.lang.String报错解决方法

    这个错的意思是:java.sql.Timestamp和java.lang.String无效的比较 错误的原因是:拿传入的时间类型参数与空字符串进行比较就会报这个异常 解决方法:只保留非null判断就可 ...

随机推荐

  1. PyQt(Python+Qt)帮助文档官网及文档下载

    一.帮助文档下载 老猿在网上找到一个Qt 5.9的帮助文档,没有找到最新版的,并且这个文档官网上没有下载,不知道源头在哪里可以下载. 文档存放在百度网盘: 链接:https://pan.baidu.c ...

  2. 派大星的烦恼MISC

    挺有意思的杂项,python将二进制转图片的时候出现的图片不像二维码,想看题解的时候发现网上的大部分题解都是直接转发,更有意思了. 题目是派大星的烦恼,给了我们一张粉红图片,放进010editor里面 ...

  3. Leetcode学习笔记(1)

    scrapy爬虫的学习告一段落,又因为现在在学习数据结构,做题平台是lettcode:https://leetcode-cn.com/ 每周都要交一次做题的笔记,所以把相关代码和思路同时放在博客上记录 ...

  4. datagrip2020最新安装破解教程方法激活码安装参数

    现在,datagrip的版本已更新至2020.3,尚未升级的用户请赶快升级. 本文教您如何安装datagrip2020.3版本并破解它. 此方法可以100%永久激活datagrip2020.3(低版本 ...

  5. Java集合源码分析(五)——HashMap

    简介 HashMap 是一个散列表,存储的内容是键值对映射. HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io.Serializable接口. HashM ...

  6. 关于Android手机CPU不同架构的问题

    1.共有7种架构 armeabiv-v7a: 第7代及以上的 ARM 处理器.2011年15月以后的生产的大部分Android设备都使用它. arm64-v8a: 第8代.64位ARM处理器,很少设备 ...

  7. PluginOK中间件高级版-支持在Chrome、Edge、Firefox等浏览器网页中真正内嵌ActiveX等控件运行的版本已获多家上市公司采购

    PluginOK(牛插)中间件(原名:本网通WebRunLocal)是一个实现WEB浏览器(Web Browser)与本地程序(Local Application)之间进行双向调用的低成本.强兼容.安 ...

  8. 【Go语言绘图】图片添加文字(一)

    前一篇讲解了利用gg包来进行图片旋转的操作,这一篇我们来看看怎么在图片上添加文字. 绘制纯色背景 首先,我们先绘制一个纯白色的背景,作为添加文字的背景板. package main import &q ...

  9. PHP面向对象的学习(封装,继承,多态)

    这个文章就是记录  巩固一下PHP的面向对象的部分 ,无非就是封装,继承,多态等等这几部分 这里参考了一位大佬总结的文章:https://www.cnblogs.com/adaia/p/6986576 ...

  10. redis 五种常见攻击方法

    如果需要大佬写好的脚本,可以直接去github上面搜 参考文章:https://www.cnblogs.com/wineme/articles/11731612.html    https://www ...