【多线程学习】不安全的集合类

「这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战

List

其实在并发的情况下List是不安全的,可以多设置几个线程同时去对List进行操作看看结果

image.png

查看运行结果

image.png

从结果可以看到报错了,java.util.ConcurrentModificationException 并发修改异常

解决方法:

  1. 最先想到的可能就是使用Vector 就可以解决。而且看源码 Vector 出现的要比 List还要早出来

  2. 使用Collections.synchronizedList(new ArrayList<>())

  3. 查看JDK文档里面有一个 CopyOnWriteArrayList 是一个线程安全的ArryList

image.png

再次运行程序,问题解决

CopyOnWriteArrayList

CopyOnWrite 写入时复制,多个线程调用的时候,在读取的时候是一个固定的List,在写入的时候复制一份避免在多个同时写入的时候覆盖,造成数据问题

CopyOnWrite 和 Vector的区别在哪?

翻看Vectror的添加方法可以看到 它有synchronized修饰,效率相对来说要低一些

image.png

再查看CopyOnWrite,里面使用的是Lock

image.png

Set

set 集合也是线程不安全的,可以将上面List的创建方式改为Set在来一次,这次可能少的线程数并不会出现问题,但是这并不代表它就是安全的,将线程数改的大一点查看运行结果

image.png

出现了 java.util.ConcurrentModificationException 所以set集合也是线程不安全的

解决办法

  1. 同样可以使用 Collections 来解决 Collections.synchronizedSet(new HashSet<>());

点进Set的添加方法,可以看到HashSet下面就是用HashMap实现的, add的本质就是map,key是无法重复的

image.png

Map

从上面的Set得到,HashMap也是不安全的,可以使用上面的例子测试一下,在多个线程的情况下依然会出现并发修改异常

image.png

解决办法:使用 ConcurrentHashMap 运行程序测试,解决问题

猜你喜欢

转载自juejin.im/post/7031928141052379150