Java高并发,ArrayList、HashSet、HashMap不安全的集合类
首先是我们的ArrayList:
这次我们讲解的是集合的不安全,首先我们都知道ArrayList吧!
List<String> list=new ArrayList<>();
首先我们拓展几个知识点,ArrayList底层是Object类型的数组,jdk7之前初始容量是10。
jdk8之后是空引用,到add之后会变成10,类似于懒加载的机制,其扩容的方式是每次扩容为之前的一半,比如10会扩容成15,15扩容成22,扩容用到的方法时Arrays的copyof方法,OK,接下来后进入主题。
我们通过Lambda表达式来生成几个线程
for (int i = 0; i < 30; i++) {
new Thread(() -> {
list.add(UUID.randomUUID().toString().substring(0, 8));//写
System.out.println(list);//读
}, String.valueOf(i)).start();
}
之后会报异常:
java.util.ConcurrentModificationException 并发修改异常
导致原因:多线程并发争抢统一资源(这里指list实例),且没加锁
那么我们有什么解决办法呢??
方法一:Vector
List<String> list = new Vector<>();
Vector集合,底层给add方法加了synchronized(重锁),同一时间段只有一个个线程,效率低,所以这就是为什么Vector集合安全效率低的原因
方法二:Collections.synchronizedList
Collections.synchronizedList(new ArrayList<>());
这是Connections的静态方法,传入一个ArrayList。
方法三:CopyOnWriteArrayList
List<String> list = new CopyOnWriteArrayList<>();
jdk1.5之后,这个JUC包当中的CopyOnWriteArrayList类,实现了List接口。
public class CopyOnWriteArrayList<E>
extends Object
implements List<E>, RandomAccess, Cloneable, Serializable
CopyOnWriteArrayList的底层:volatile Object[] array
其add()方法里面加了锁ReentrantLock:写前复制,length+1
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();
}
}
注意:CopyOnWriteArrayList的扩容同样用的是Arrays工具类的copyof()方法,但一次扩容1
接着我们来看Set集合:
同样扩展点知识点,HashSet底层数据结构是HashMap,HashSet源码构造器是new HashMap(),
map集合添加元素,丢进去的是K-V键值对
但是set是无序的集合,set的元素添加是对一个对象进去。数量对不上啊,这不是互相矛盾么?所以接下来分析HashSet的底层实现源码:
HashSet的add方法实际上调的是map的put方法:,set添加的元素就是put()里面的key,因为set不会重复,keys也就不会重复
PRESENT实际上就是一个object常量,value并不重要
同样的步骤:
Set<String> set=new HashSet<>();
for(int i=0;i<30;i++){
new Thread(()->{
set.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(set);
},String.valueOf(i)).start();
}
同样是报错:
java.util.ConcurrentModificationException
解决方案:
方法一:Collections.synchronizedSet
Set<String> set=Collections.synchronizedSet(new HashSet<>());
方法二:CopyOnWriteArraySet
Set<String> set=new CopyOnWriteArraySet();
也是JUC的里的类,其构造器是new CopyOnWriteArraySet();
public class CopyOnWriteArraySet<E>
extends AbstractSet<E>
implements Serializable
然后就是我们的Map:
扩展知识:HashMap(无序无重复)底层是数组+链表(单向)+红黑树。
HashMap存的是node节点,node里面存K-V键值对,node里面存的是Key-Value,HashMap初始容量为16,负载因子为0.75(到16*0.75的时候扩容)。每次扩容为原值得一倍
初始容量和负载因子可以通过构造器来改。
Constructor and Description
HashMap()
构造一个空的 HashMap ,默认初始容量(16)和默认负载系数(0.75)。
HashMap(int initialCapacity)
构造一个空的 HashMap具有指定的初始容量和默认负载因子(0.75)。
HashMap(int initialCapacity, float loadFactor)
构造一个空的 HashMap具有指定的初始容量和负载因子。
HashMap(Map<? extends K,? extends V> m)
构造一个新的 HashMap与指定的相同的映射 Map 。
同样的操作:
Map<String, String> map = new HashMap<>();
for (int i = 0; i < 30; i++) {
new Thread(() -> {
map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 8));
System.out.println(map);
}, String.valueOf(i)).start();
}
同样的会报错:
java.util.ConcurrentModificationException
解决办法:
Map<String, String> map = new ConcurrentHashMap();
Java.util.concurrent包下的ConcurrentHashMap:
public class ConcurrentHashMap<K,V>
extends AbstractMap<K,V>
implements ConcurrentMap<K,V>, Serializable
这次就是本次讲解的JUC之集合不安全,希望能帮助到大家,如果有更好的建议,欢迎大家留言!
Java高并发,ArrayList、HashSet、HashMap不安全的集合类的更多相关文章
- Java高并发如何解决
Java高并发如何解决 对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题,但话又说回来了,既然逃避不掉,那我们就坦然面对吧 ...
- 转载:Java高并发,如何解决,什么方式解决
原文:https://www.cnblogs.com/lr393993507/p/5909804.html 对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并 ...
- Java高并发综合
这篇文章是研一刚入学时写的,今天整理草稿时才被我挖出来.当时混混沌沌的面试,记下来了一些并发的面试问题,很多还没有回答.到现在也学习了不少并发的知识,回过头来看这些问题和当时整理的答案,漏洞百出又十分 ...
- 【转】Java高并发,如何解决,什么方式解决
原文地址:https://www.cnblogs.com/lr393993507/p/5909804.html 对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了. ...
- 《实战Java高并发程序设计》读书笔记
文章目录 第二章 Java并行程序基础 2.1 线程的基本操作 2.1.1 线程中断 2.1.2 等待(wait)和通知(notify) 2.1.3 等待线程结束(join)和谦让(yield) 2. ...
- java高并发系列 - 第26篇:学会使用JUC中常见的集合,常看看!
这是java高并发系列第26篇文章. 环境:jdk1.8. 本文内容 了解JUC常见集合,学会使用 ConcurrentHashMap ConcurrentSkipListMap Concurrent ...
- 如何解决java高并发详细讲解
对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研 ...
- Java高并发系列——检视阅读
Java高并发系列--检视阅读 参考 java高并发系列 liaoxuefeng Java教程 CompletableFuture AQS原理没讲,需要找资料补充. JUC中常见的集合原来没讲,比如C ...
- Java高并发 -- 并发扩展
Java高并发 -- 并发扩展 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 死锁 死锁是指两个或两个以上的事务在执行过程中,因争夺锁资源而造成的一种互相等待的现象, ...
- Java高并发 -- 线程池
Java高并发 -- 线程池 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 在使用线程池后,创建线程变成了从线程池里获得空闲线程,关闭线程变成了将线程归坏给线程池. ...
随机推荐
- java多线程-补充-面试
1.背景 在这个课程之前我们已经讲了2个关于多线程的课程 一个是主要是关于多线程基础的: 另一个主要是关于JUC的: 今天我们对之前课程中没有讲到的或者重要的或者是童鞋们反馈的技术点做一个补充讲解 当 ...
- nginx实战教程
大纲 为了让大家更快的学会,该博客中的内容录制成了视频课程:马上在线学习 1.什么是nginx Nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器. 由 ...
- bmp位图文件信息结构体
/************************************************* * * file name:BmpInfoStruct.c * author :momolyl@1 ...
- 关于mysql配置文件中jdbc url 的记录
版本不同 url不同 大同小异 基本就是不同参数配置的区别 maven 仓库地址 https://mvnrepository.com/artifact/mysql/mysql-connector-ja ...
- .Net Aspire次体验
上次用上了在微软MVP的带领下用上了Aspire,在开发阶段隐藏了细节,什么都不用做,点个调试按钮就跑起来了,可是部署时出现了难题, 因为发布时只能选择Azure环境,为此注册了Azure,开了科网. ...
- Cookie、localStorage 和 sessionStorage 的区别及应用实例
在前端开发中,持久化数据存储是一个非常常见的需求.为了实现这一点,浏览器提供了多种方式,包括 Cookie.localStorage 和 sessionStorage.这三者各有优劣,适用于不同的场景 ...
- NVIDIA vGPU vApps/vWS/vCS适配GPU版本介绍
NVIDIA vGPU 12.0版本-vGPU版本名称变化 - 注: 2021年1月生效 最新名称 NVIDIA Virtual PC (vPC) -曾用名称 NVIDIA GRID Virtual ...
- 我当年如何入门Linux的?-zdc的那些往事
一.通信当年的疯狂 还记得09年初, 山寨机横行, 市场上手机主要还是塞班os, 小灵通还没有退出市场, 基于安卓的智能手机陆续推出. 没有王者荣耀,更没有微信, 小米的米聊还在ppt里: 那个时候网 ...
- freertos学习笔记(十)事件标志组
事件标志组 相当于用户平时定义的Flag,事件标志,不过freertos支持将该标志组作为启动task的条件 概述 分为8位和24位的模式(通过设置宏来配置) 每一位有0和1两个状态 用法 用于平常程 ...
- python pyqt6 设定logo图标
如果是Window self.setWindowIcon(QIcon(get_icon('logo.png'))) 如果是Dialog self.login_dialog.setWindowIcon( ...