Java面试笔记:Java线程安全的集合类有哪些?线程不安全的集合类有哪些?ArrayList为什么会发生并发修改异常?
创始人
2024-01-20 14:40:12
0

一、Java的集合类有哪些?

二、如何定义集合是线程不安全的?
        当多个并发同时对线程不安全的集合进行增删改的时候会破坏这些集合的数据完整性,例如:当多个线程访问同一个集合或Map时,如果有超过一个线程修改了ArrayList集合,则程序必须手动保证该集合的同步性。这就说明集合是线程不安全的。

三、实例:验证ArrayList线程不安全,抛出异常 ConcurrentModificationException 

import java.util.*;
/*** @author 蓝多多的小仓库* @title: mytest* @projectName test* @description: ldd_annotation* @date 2022/11/10 16:39*/
public class mytest {public static void main (String[] args) {List list = new ArrayList();for (int i = 0; i < 10; i++) {final int j = i;new Thread(() -> {list.add(j);System.out.println(list);}, "" + i).start();}}
}

运行结果(结果不是唯一的,也有可能不抛出异常,你可以多运行几次): 

四、Java线程安全的集合类有哪些?

        线程安全类是确保类的内部状态以及从方法返回的值在从多个线程并发调用时是正确的类。Java线程安全的集合有Vector、HashTable、Stack、ArrayBlockingQueue、ConcurrentHashMap、ConcurrentLinkedQueue等。

        Vector:相当于 ArrayList 的翻版,是长度可变的数组,只要是关键性的操作,方法前面都加了synchronized关键字修饰,来保证线程的安全性。Vector类可以支持add(),remove(),get(),size()等方法,实例如下:

import java.util.*;
public class mytest {public static void main (String[] args) {Vector vector = new Vector();vector.add(2);vector.add(4);vector.add("LDD");vector.add(1);vector.add("LYD");System.out.println("向量: " + vector);vector.remove(1);System.out.println("移除元素后向量为: " + vector);}
}


        Hashtable:是一个线程安全的集合,是单线程集合,它给几乎所有public方法都加上了synchronized关键字。所以相较于Hashmap是线程安全的。

        ArrayBlockingQueue:是一个阻塞队列,底层使用数组结构实现,按照先进先出(FIFO)的原则对元素进行排序,是线程安全的。

        ConcurrentLinkedQueue:是一种FIFO的无界队列,是线程安全的,它适用于“高并发”的场景。

        ConcurrentHashMap:采用了分段锁(Segment),是一种高效但是线程安全的集合。
        Stack:栈,也是线程安全的,继承于Vector,栈后进先出。Stack类可以支持许多操作,比如push、pop、peek、search、empty等。实例:

import java.util.*;
public class mytest {public static void main (String[] args) {Stack stack = new Stack();stack.push(2);stack.push(4);stack.push(1);Integer num1 = (Integer) stack.pop();System.out.println("出栈元素是: " + num1);Integer num2 = (Integer) stack.peek();System.out.println("栈顶元素是: " + num2);}
}

        那么使用ArrayList、HashMap,需要线程安全怎么办呢?为了保证集合既是安全的而且效率高,Collections为我们提出了解决方案,把这些集合包装成线程安全的集合。使用Collections装饰的线程安全集合如下:

 Collection synchronizedCollection(Collection c); //返回指定collection 对应的线程安全的collection。
static  List synchronizedList(List list); //返回指定List对象对应的线程安全的List对象。
static  Map synchronizedMap(Map m); //返回指定Map对象对应的线程安全的Map对象。
static  Set synchronizedSet(Set s); //返回指定Set对象对应的线程安全的Set对象。
static  SortedMap synchronizedSortedMap(SortedMap m); //返回指定SortedMap对象对应的线程安全的SortedMap对象。

        java.util.concurrent.*下的线程安全集合类:如:CopyOnWriteArrayList、 CopyOnWriteArraySet等,它们里面包含三类关键词: Blocking、CopyOnWrite、Concurrent Blocking,大部分实现基于锁,并提供用来阻塞的方法。

        关于CopyOnWriteArrayList是怎么保证线程安全的?请参考上一篇文章:Java面试笔记:CopyOnWriteArrayList是怎么保证线程安全的?_蓝多多的小仓库的博客-CSDN博客

五、线程不安全的集合类有哪些?

        Hashmap:HashMap在put操作的时候,如果插入的元素超过了容量(由负载因子决定)的范围就会触发扩容操作,就是resize,这个会重新将原数组的内容重新hash到新的扩容数组中,在多线程的环境下,存在同时其他的元素也在进行put操作,如果hash值相同,可能出现同时在同一数组下用链表表示,造成闭环,导致在get时会出现死循环,所以HashMap是线程不安全的。

        ArrayList: List 对象在做 add 时,执行 Arrays.copyOf 的时候,返回一个新的数组对象。当有线程 A、B… 同时进入 grow方法,多个线程都会执行 Arrays.copyOf 方法,返回多个不同的 elementData 对象,假如,A先返回,B 后返回,那么 List.elementData ==A. elementData,如果同时B也返回,那么 List.elementData ==B. elementData,所以线程B就把线程A的数据给覆盖了,导致线程A的数据被丢失。也可以参考上面提供的实例验证ArrayList线程不安全,抛出异常 ConcurrentModificationException 来理解ArrayList为什么是不安全的。

        LinkedList:与Arraylist线程安全问题相似,线程安全问题是由多个线程同时写或同时读写同一个资源造成的。

        HashSet:底层数据存储结构采用了Hashmap,所以Hashmap会产生的线程安全问题HashSet也会产生。
        TreeSet、TreeMap等

六、ArrayList为什么会发生并发修改异常?那么如何避免ArrayList的并发问题?

        ArrayList是线程不安全的,在多线程并发访问的时候可能会出现问题,会存在线程B把线程A的数据给覆盖了,导致线程A的数据被丢失的情况,也有可能在扩容时有数组索引越界的异常产生。解决方案:

(1)使用Collections.synchronizedList()方法对ArrayList对象进行包装

ArrayList arraylist = Collections.synchronizedList(new ArrayList());

(2)使用并发容器CopyOnWriteArrayList

CopyOnWriteArrayList list = new CopyOnWriteArrayList();

        详情请参考:ArrayList为什么会出现并发问题以及相应的解决办法_Max的外企搬砖随笔的博客-CSDN博客

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...