Java8 parallelStream使用注意!
【摘要】 使用Java8 parallelStream并行流,抛出数组越界异常
parallelStream是线程不安全的,使用以下代码时
集合里面可能会存在null元素或者抛出下标越界的异常信息
原因:ArrayList不是线程安全的集合,add方法在多线程环境下会存在并发问题
存在null元素原因:
数组越界的原因:
先看list的add源码
public boolean add(E e) {
ensureCapacityInternal(size + 1);
elementData[size++] = e;
return true; }
假设当前数组刚好只能添加一个元素,两个线程同时进入: ensureCapacityInternal(size + 1),同时读取的size值,加1后进入ensureCapacityInternal都不会导致扩容,退出ensureCapacityInternal后,两个线程同时elementData[size] = e,线程B的size++先完成,假设此刻线程A读取到了线程 B的更新,线程A再执行size++,此时size的实际值就会大于数组的容量,这样就会发生数组越界异常。
解决办法:
-
不使用parallelStream,因为parallelStream是并行流,仅在CPU密集型下可以提高运行效率,在循环中计算量不是特别大的时候,直接使用原始集合遍历或者stream()
-
在parallelStream中的操作使用线程安全的集合,如
Collections.synchronizedList(new ArrayList());
这种处理只能保证集合中的数据不会存在null值和集合中不会丢失数据,但是不保序
注意:使用ForkJoinPoll,提交任务也不能保证集合中不存在null值
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)