java-基础并行流

1. 介绍

  1. parallel方法可以将任意的顺序流转换为并行流
  Stream<String> parallelwords =Stream.of(wordArray).parallel()
  1. 只要在终结方法执行时流处于并行模式,所有的中间流操作就都将被并行化。
  2. 当流操作并行运行时,其目标是让其返回结果与顺序执行时返回的结果相同。重要的是,这些操作是无状态的,并且可以以任意顺序执行

2. Spliterator

对数据拆分

3. 线程池

ForkJoinPool.commonPool 返回的全局 fork-ioin池。

Runtime.getRuntime().availableProcessors() 默认会开核心减一的线程数

var pool = new ForkJoinPool(2);
var max = pool.submit(() -> list.parallelStream().max(Comparator.naturalOrder())).get();

也可以自定义其他的线程池

并行流使用的是只有在操作不会阻塞并且我们不会将这个池与其他任务共享的情况下,这种方式才不会有什么问题

4. 线程安全问题

4.1. 说明

var shortMords = new int[12];
words.parallelStream().forEach(s->{ if(s.length()< 12)shortWords[s.length()]++;});
System.out.printLn(Arrays.toString(shortwords)

这是一种非常糟糕的代码。传递给forEac的函数会在多个并发线程中运行,每个都会更新共享的数组,这是一种经典的竞争情况。如果多次运行这个程序,你很可能就会发现每次运行都产生不同的计数值,而且每个都是错的

如果用长度将字符串分组,然后分别对它们进行计数,那么就可以安全地并行化这项计算

Map<Integer, Long> shortWordCounts= words.parallelStream()
       .filter(5-> s.lenqth()< 12)
      .collect(groupingBy(String::length, Ccountingt)
  1. 默认情况下,从有序集合(数组和列表)、范围、生成器和迭代器产生的流,或者通过调用Stream.sorted产生的流,都是有序的。它们的结果是按照原来元素的顺序累积的,因此是完全可预知的。如果运行相同的操作两次,将会得到完全相同的结果。
  2. 排序并不排斥高效的并行处理。例如,当计算stream.map(fun)时,流可以被划分为n部分,它们会被并行地处理。然后,结果将会按照顺序重新组装起来
  3. distinct 会保留所有相同元素中的第一个,这对并行化是一种阻碍,因为处理每个部分的线程在其之前的所有部分都被处理完之前,并不知道应该丢弃哪些元素。如果可以接受保留唯一元素中任意一个的做法,那么所有部分就可以并行地处理(使用共享的集合来跟踪重复元素)

4.2. 当放弃排序需求时,有些操作可以被更有效地并行化

Stream<String> sample = words.paralleLStream().unordered().Limit(n)

4.3. Collectors.groupingByConcurrent

使用了共享的并发映射表

Map<Integer,List<String>> result = words.parallelStream().collect(

Collectors.groupingByConcurrent(String::Length))

5. 文件

Java9之前,对Files.lines方法返回的流进行并行化是没有意义的。因为数据是不可分割的,所以我们只能在读取文件的后半部分之前读取前半部分。现在,该方法使用的是内存映射文件,因此可以有效地进行分割。如果想要处理一个大型文件的各个行,并行化这个流可能会提高性能。

6. 注意

  1. 并行化会导致大量的开销,只有面对非常大的数据集才划算
  2. 只有在底层的数据源可以被有效地分割为多个部分时,将流并行化才有意义
  3. 并行流使用的线程池可能会因诸如文件 I/O或网络访问这样的操作被阻塞而饿死。只有面对海量的内存数据和运算密集处理,并行流才会工作最佳
  • 21
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值