Java 的常用类集合介绍![](https://img-blog.csdnimg.cn/20190920152306197.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNjA3OTg2NQ==,size_16,color_FFFFFF,t_70)
从线程安全的角度去分析每个集合类的使用场景
一、概念
- 线程安全:当多个线程同时访问同一个资源时,不会出现与预期结果不一致的现象,反之则是线程不安全的
- 线程工作原理:JVM 中有一个 main memory对象,每个线程都有自己的working memory,一个线程对于一个变量variable进行操作的时候,都需要在自己的 working memory 里创建一份copy,操作完之后再写入 main memory 。当多个线程同时操作同一个变量 variable ,就可能出现预期之外的结果
- 如何保证线程安全:对存在并发的资源进行 synchronized 加锁的操作,让线程在访问资源进行排序,保证同一时刻仅有一个线程获取资源锁,直到该资源被释放
二、集合分类
- Vector 线程安全
- HashTable 线程安全
- ArrayList 非线程安全
- LinkedList 非线程安全
- HashMap 非线程安全
- HashSet 非线程安全
三、集合的性能比较
-
Vector:底层操作的是数组,实现了List的接口,因为是线程同步的所以在非多线程环境中,Vector 对于元素的查询、添加、删除和跟新操作都是慢于ArrayList,Vector 可实现自动增长的对象数组。java.util.vector 提供了向量类(vector)以实现动态数组的功能,创建一个向量类的对象后,可以往其中随意插入不同类的对象,即不需要考虑类型也不需要预先选定向量的容量,并可以方便查找,ArrayList数组容量每次增长是50%,而Vector是原来容量的一倍,数组容量也是可以指定的
-
ArrayList:追加数据到集合的末尾以及随机访问其中元素时,ArrayList的性能表现更好点,底层操作也是数组,它允许对元素进行随机访问,当数组的容量达到 设定阈值时,数组会动态的扩展,数组会将已有的数据copy到新的存储空间 ,所以当数组进行复制,插入,移动时,响应的操作耗时也会增加
-
LinkedList:当对一列数据的进行插入,删除操作比较频繁时,建议使用LinkedList,其底层操作的是双向链表,插入和删除比较块,但是随机访问和遍历比较慢
性能 | 线程安全 | 增长容量 | |
Vector | 低 | 安全 | 1倍 |
ArrayList | 高 | 不安全 | 50% |
Map集合详解推荐博文: https://blog.csdn.net/ZHAOJING1234567/article/details/90244037
- Map的线程安全的有 HashTable 和 ConcurrentHashMap 两者均用于多线程的环境,在数据增多时Hash的性能久开始呈现急剧下降的趋势,迭代时资源被锁定时间高于 ConcurrentHashMap,HashTable资源锁定是将整个map集合进行锁定,而ConcurrentHashMap 将 map 进行了分割(segmentation),锁定只针对某个 segmentation 所以其他线程并不需要等迭代完成才能访问资源
- HashMap 采用数据的方式存储 k-v 格式的Entry对象,无容量限制;基于 key 的 hash 查找 Entry 对象存放到数组的位置,当hash冲突时采用链表的方式去解决,当数组的容量扩增时,会重新计算 hash 值,并复制到新的数组中。非线程安全,遍历使用的 Iterator 迭代器,允许 key 和 value 都为 null。而 HashTable 不允许