Java@Java并发编程之支持并发的list集合你知道吗


Java@Java并发编程之支持并发的list集合你知道吗
文章图片
Java@Java并发编程之支持并发的list集合你知道吗
文章图片
Java@Java并发编程之支持并发的list集合你知道吗
文章图片
Java@Java并发编程之支持并发的list集合你知道吗
文章图片
Java并发编程之-list集合的并发.
我们都知道Java集合类中的arrayList是线程不安全的 。 那么怎么证明是线程不安全的呢?怎么解决在并发环境下使用安全的list集合类呢?
本篇是《凯哥(凯哥Java:kagejava)并发编程学习》系列之《并发集合系列》教程的第一篇:
本文主要内容:怎么证明arrayList不是线程安全的?怎么解决这个问题?以及遇到问题解决的四个步骤及从源码来分析作者思路 。
一:怎么证明arrayList在并发情况下是线程不安全的呢?创建一个list用多个线程向list中添加数据 。 来看看结果
查看运行结果:
我们发现了一个异常:java.util.ConcurrentModificationException
java.util.ConcurrentModificationException是什么这个异常什么意思呢?我们来看看这个异常源码中类的注释信息:
This exception may be thrown by methods that have detected concurrent(此异常可能由检测到并发的方法引发).
一般可以理解为 , 这是并发导致的异常 。 那么在并发情况下出现了异常 。 是不是从侧面说明arrayList是不安全的呢?
二:怎么解决这个问题这里凯哥顺便说下 , 解决问题的一般步骤 。
1:怎么操作导致的故障及现象是什么?操作:多个线程对list进行add添加操作的时候
结果:抛出了java.util.ConcurrentModificationException异常信息
2:分析产生这个问题的原因举个现实生活中的例子 。 签到表 , 这个大家都见过吧 , 应该都签到过吧 。 比如现在有个会议很多人来参与 , 需要签到 。 现在 , 司小司正在签到表上写自己的名字时候 , 小明非要看签到表上面有没有自己名字 。 因为司小司正在签到进行中 , 小明硬是要查看 , 把签到表抢过去 , 结果就是签到表被撕坏了或者是司小司的笔在签到表上留下了长长的痕迹 。 如果上面这个例子用计算机角度分析的话 。
两个线程(司小司和小明)对一个共享变量(签到表 , 可以理解为是人名的集合)进行读写操作(司小司签到是写操作 , 小明要查看自己是否签到了 , 可以理解为读操作) , 因为两个线程都来竞争共享资源 。 后果就是签到表被撕坏了或者是司小司的笔在签到表上留下了长长的痕迹 。 异常现象 。 用到上面我们多个线程对list进行操作的时候 , 就抛异常了多线程并发修改异常信息 。
3:解决方案是什么?1:使用线程安全的List的子类VectoryList list = new Vectory();
查看vectory的add方法源码:
发现 , 原来vector的add方法是加的并发锁来保证线程安全的
2:使用collections工具类的sync方法List list = Colletcions.synchronizedList(new ArrayList<>());
查看源码:
原来都是synchronized的 。
我们在来看看synchronizedList方法上面的注释 。
发现 , 原来源码中是把整个list对象作为同步锁的锁 。 这样来保证线程安全的
4:解决方案可以优化吗?优化的建议是什么?我们知道synchronized关键字是同步锁机制 。 强制并行转化成串行的一种方案 。 这种对性能消耗比较大 。 有没有更其他可以优化的方案吗?