我们知道ArrayList是线程不安全,请设计一个不安全的案例并给出解决方案?
16lz
2021-03-21
示例如下
List<String> list = new ArrayList<String>(); 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(); ; } }
结果如下:
故障现象
ConcurrentModificationException :当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。
解决方案
- 方案一:new Vector<>();
- 方案二:Collections.synchronizedList(new ArrayList<>())
- 方案三:JUC的 new CopyOnWriteArrayList()
导致原因
并发争抢导致,参考花名册签名情况,一个人正在写入,另外一个同学过来抢夺,导致数据不一致异常,并发修改异常
优化建设
CopyOnWrite 写时复制:
往一个容器添加元素的时候,不直接往当前容器Object[]添加,而是先将当前容器Object[]进行copy,只复制出一个新的容器object[] newelements;然后新的容器添加元素,添加完元素之后,再将原有容器的引用指向新的容器setArray(newelements);
这样的好处是可以对CopyOnWrite容器进行并发的读,而不需要枷锁,因为当前容器不会添加任何元素,所有CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器
HashSet 的底层是什么?
1.HashSet的底层是HasMap
public HashSet() { map = new HashMap<>(); }
2.使用map的put方法存储,key存具体的值,value存Object对象
private static final Object PRESENT = new Object(); public boolean add(E e) { return map.put(e, PRESENT)==null; }
集合类线程不安全解决的类:
CopyOnWriteArrayList list; CopyOnWriteArraySet set; ConcurrentHashMap map;
©著作权归作者所有:来自51CTO博客作者l363130002的原创作品,如需转载,请注明出处,否则将追究法律责任好知识,才能预见未来
赞赏
0人进行了赞赏支持
更多相关文章
- 我的第一款 Drone 插件
- 面试必备,电商系统中并发测试是怎样进行的?
- JavaMySQL面试题,如何书写 update 避免表锁?
- MySQL:表级锁、行级锁、共享锁、排他锁、乐观锁、悲观锁
- Java并发编程学习笔记2
- HULK容器镜像仓库简介
- Docker容器引擎的安装部署
- 降级?限流?程序员双十一过后如何5元花3天?
- 携程万台规模容器云平台运维管理实践