「这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战」
List
其实在并发的情况下List是不安全的,可以多设置几个线程同时去对List进行操作看看结果
查看运行结果
从结果可以看到报错了,java.util.ConcurrentModificationException 并发修改异常
解决方法:
-
最先想到的可能就是使用Vector 就可以解决。而且看源码 Vector 出现的要比 List还要早出来
-
使用
Collections.synchronizedList(new ArrayList<>())
-
查看JDK文档里面有一个 CopyOnWriteArrayList 是一个线程安全的ArryList
再次运行程序,问题解决
CopyOnWriteArrayList
CopyOnWrite 写入时复制,多个线程调用的时候,在读取的时候是一个固定的List,在写入的时候复制一份避免在多个同时写入的时候覆盖,造成数据问题
CopyOnWrite 和 Vector的区别在哪?
翻看Vectror的添加方法可以看到 它有synchronized修饰,效率相对来说要低一些
再查看CopyOnWrite,里面使用的是Lock
Set
set 集合也是线程不安全的,可以将上面List的创建方式改为Set在来一次,这次可能少的线程数并不会出现问题,但是这并不代表它就是安全的,将线程数改的大一点查看运行结果
出现了 java.util.ConcurrentModificationException 所以set集合也是线程不安全的
解决办法
- 同样可以使用 Collections 来解决
Collections.synchronizedSet(new HashSet<>());
点进Set的添加方法,可以看到HashSet下面就是用HashMap实现的, add的本质就是map,key是无法重复的
Map
从上面的Set得到,HashMap也是不安全的,可以使用上面的例子测试一下,在多个线程的情况下依然会出现并发修改异常
解决办法:使用 ConcurrentHashMap 运行程序测试,解决问题