java8的ParallelStream踩坑记录

简介: java8中的新特性stream流处理,让集合操作变得非常的简单,但是因为没有源码支持,所以里面有很多坑,只有踩过才知道首先上代码图1-1代码很简单,就是利用并行流把一个list里面的数据导入到另外一个list中,看起来看简单,接下来...

java8中的新特性stream流处理,让集合操作变得非常的简单,但是因为没有源码支持,所以里面有很多坑,只有踩过才知道

首先上代码

img_a8a29d4f98f4d91dc73381f261f7fb39.png
图1-1

代码很简单,就是利用并行流把一个list里面的数据导入到另外一个list中,看起来看简单,接下来我们看一下执行结果

img_04610a919da2bfd1f756247a332f25e1.png
图1-2

此处我们发现执行结果中,导入的list数据竟然少了一个??????,从代码上看貌似没啥问题啊???

多线程并发出现了这种问题,我们讲代码稍微修改一下,就可以

img_ada0bab790c0f489ffff4c31f04c097d.png
图1-3

执行结果

img_861853b326c673c1fcda83bd48dfd511.png
图1-4

我们来找一个出现问题的原因,此处,我们重复运行这段代码,,发现每次缺少的数字并不相同,而且缺少数字的个数也是一样,我们此处可以判断,在并行操作中,出现了线程安全问题,并行操作中,只有parallelStorage.add(e);的时候存在,我们把这个类修改成SynchronizedList类型的list,就可以解决这种问题,类似于图1-3中的解释

比较完整的解释:

Arraylist本身底层是一个数组,多线程并发下线程并不安全,操作出现的原因无非就是多个线程赋值可能同时操作同一个地址,后赋值的把先赋值的给覆盖掉了,才会出现这种问题。


附github地址:https://github.com/kevin0016/kevin-java-wallow

相关文章
|
Java
java8中修改parallelStream默认并发数
java8中修改parallelStream默认并发数
1841 0
java8中修改parallelStream默认并发数
|
6月前
|
Java
Java并行流问题之parallelStream的使用方式
Java并行流问题之parallelStream的使用方式
125 1
|
7月前
|
Java 数据处理
Java8的新特性parallelStream()的概念、对比线程优势与实战
parallelStream() 是 Java 8 中新增的一个方法,它是 Stream 类的一种扩展,提供了将集合数据并行处理的能力。普通的 stream() 方法是使用单线程对集合数据进行顺序处理,而 parallelStream() 方法则可以将集合数据分成多个小块,分配到多个线程并行处理,从而提高程序的执行效率。
580 3
|
安全 Java
Java8中的Stream()与ParallelStream()的区别
Java8中的Stream()与ParallelStream()的区别
85 0
|
并行计算 算法 安全
谨慎使用 Java8 新特性 ParallelStream并行流
谨慎使用 Java8 新特性 ParallelStream并行流
1044 0
|
安全 Java
使用Java8新特性parallelStream遇到的坑
使用Java8新特性parallelStream遇到的坑
|
前端开发 安全 Java
面试官:java8中parallelStream提升数倍查询效率是怎样实现的
业务场景 在很多项目中,都有类似数据汇总的业务场景,查询今日注册会员数,在线会员数,订单总金额,支出总金额等。。。这些业务通常都不是存在同一张表中,我们需要依次查询出来然后封装成所需要的对象返回给前端。那么在此过程中,就可以把这个接口中“大任务”拆分成N个小任务,异步执行这些小任务,等到最后一个小任务执行完,把所有任务的执行结果封装到返回结果中,统一返回到前端展示。
面试官:java8中parallelStream提升数倍查询效率是怎样实现的
|
3天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
5天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
5天前
|
消息中间件 缓存 安全
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。