首页 > 编程语言 >解锁多核处理器的力量:探索数据并行化在 Java 8 Stream 中的应用

解锁多核处理器的力量:探索数据并行化在 Java 8 Stream 中的应用

时间:2023-11-06 11:36:34浏览次数:31  
标签:fork Java Stream 化在 并行 并行处理 任务 处理器 数据

在 Java 8 中引入的 Stream 为集合数据的处理带来了现代化的方式,而数据并行化则进一步提升了处理速度,充分发挥了多核处理器的优势。本篇博客将详细介绍数据并行化在 Java 8 Stream 中的应用,以及如何利用并行流处理大量数据。

什么是数据并行化

数据并行化是指将任务分解成多个子任务,并将这些子任务分配给多个处理单元(如多个 CPU 核心)并行执行。在集合数据的处理中,可以将数据划分为多个小块,然后在不同的处理单元上并行处理,从而加快处理速度。

在大量数据处理上,数据并行化可以大量缩短任务的执行时间,将一个数据分解成多个部分,然后并行处理,最后将多个结果汇总,得到最终的结果

并行和并发

并发(Concurrency)

并发是指多个任务在同一时间段内交替执行。它可以在单个处理器上通过任务切换(上下文切换)实现,也可以在多个处理器上同时进行。在并发模式下,多个任务在微观上交替执行,但在某个时间段内只有一个任务在执行。这种模式通常用于提高系统的效率和响应能力,适用于 I/O 密集型任务,如网络通信、文件读写等。

解锁多核处理器的力量:探索数据并行化在 Java 8 Stream 中的应用_数据

并行(Parallelism)

并行是指多个任务在同一时刻同时执行,每个任务在不同的处理器核心上独立运行。与并发不同,并行是在宏观上实现多任务的真正同时执行。这种模式通常用于提高计算密集型任务的处理速度,如科学计算、图像处理等。

解锁多核处理器的力量:探索数据并行化在 Java 8 Stream 中的应用_Java_02

总结

  • 并发关注任务之间的交替执行,是一种在时间上的重叠。
  • 并行关注任务在同一时刻的同时执行,是一种在时间上的重合。
  • 并发适用于提高系统效率和响应能力,适用于 I/O 密集型任务。
  • 并行适用于提高计算速度,适用于计算密集型任务。

并行流的使用示例

Java 8 引入了并行流,它使得数据并行化变得非常容易。只需将顺序流转换为并行流,即可实现并行处理。以下是一个简单的示例代码:

public class MaxDemo {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);
        int sum = numbers.parallelStream().mapToInt(i -> i).sum();
        System.out.println(sum);
    }

在上述示例中,通过 parallelStream() 方法将顺序流转换为并行流,从而实现了并行处理。接着,我们对流进行了过滤和映射操作,最后计算了偶数的总和。

注意事项和适用场景

虽然并行流可以提升处理速度,但并不是在所有情况下都适用。不要陷入一个误区:并行一定比串行快。并行在不同的情况下不一定比串行快。影响并行性能有以下因素:

数据量

如果数据量太小,会直接影响到并行处理的性能。因为在并行内部实现涉及到 fork/join 的操作,这些操作的本身就存在性能的开销,只有当数据量很大的时候,使用并行处理才有意义

源数据结构

fork 时会对源数据进行分割,数据源的特性直接影响到 fork 的性能,从而导致并行流性能很慢

  • arrayList、array、IntStream.range,是最容易分割的,因为都支持随机读取
  • HashSet、TreeSet, 相对来说比较容易分割,但是因为内部数据结构,很难被平均分解
  • LinkedList、Streams.iterate、BufferedReader.lined 不容易分分割,因为长度未知,无法确定分在哪里进行分割

装箱拆箱

尽量使用基本数据类型,避免装箱和拆箱

CPU 核数

fork 产生的数量是与 CPU 核数相关,可用的核数越多,获取的性能提升越大

单元处理开销

花在流中每个元素的时间越长,并行操作带来的性能提升就越明显

并行流原理介绍

并行流的工作原理可以分为以下几个步骤:

  1. 数据切分:初始数据被分成多个小块,每个块包含一部分元素。
  2. 并行处理:各个处理器核心同时对不同的数据块执行相同的操作。
  3. 结果合并:各个处理器核心处理完成后,将结果合并为最终结果。

并行流在底层的实现是沿用 Java7 提供的 fork 和 join 分解合并框架实现的,fork 根据 cpi 核数进行数据分开,join 对各 forn 进行合并。实现过程如下图所示:

解锁多核处理器的力量:探索数据并行化在 Java 8 Stream 中的应用_并行处理_03

总结

数据并行化是 Java 8 Stream 中的重要特性,可以显著提升大规模数据处理的速度。通过将顺序流转换为并行流,我们可以利用多核处理器的优势,实现高效的并行处理。然而,在使用并行流时需要注意线程安全和适用场景,以充分发挥其优势。在实际开发中,根据数据规模和操作类型的不同,合理使用并行流将为你的程序带来性能的提升。

标签:fork,Java,Stream,化在,并行,并行处理,任务,处理器,数据
From: https://blog.51cto.com/u_14129797/8202927

相关文章

  • Apache Paimon 实时数据湖 Streaming Lakehouse 的存储底座
    摘要:本文整理自阿里云开源大数据表存储团队负责人,阿里巴巴高级技术专家李劲松(之信),在StreamingLakehouseMeetup的分享。内容主要分为四个部分:流计算邂逅数据湖PaimonCDC实时入湖Paimon不止CDC入湖总结与生态一、流计算邂逅数据湖流计算1.0实时预处理流计算1.0架构截止......
  • Java 获取自定义注解 字段值 及 注解值
    自定义注解packagecom.jianmu.bean.annotation;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;/**[email protected]......
  • java随机数
    在Java中生成随机数可以使用java.util.Random类或者java.lang.Math类的静态方法,也可以使用Java8引入的java.util.concurrent.ThreadLocalRandom类。参考文章:java怎么产生随机数使用java.util.Random类:importjava.util.Random;publicclassMain{publicstaticvoid......
  • java数组最大值
    参考文章:java数组求最大值在Java中,你可以通过遍历数组元素来找到数组中的最大值。以下是两种常见的方法:使用循环遍历数组publicclassMain{publicstaticvoidmain(String[]args){int[]array={10,5,8,2,7};//假设数组的第一个元素是最大......
  • Shell系列---【常用脚本之---java启动脚本:run.sh】
    run.sh#!/bin/sh-lapplication=node_exporterPORT=1888CUR_IP=${hostname-I|awk'{print$1}'}command="/opt/app/middles/node_exporter/node_exporter--web.listen-address=:$PORT"#停止stop(){ echo"=============================......
  • Java设计模式之桥接模式
    桥接(Bridge)模式的定义如下:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。假如你有一个几何形状(Shape)类,从它能扩展出两个子类:圆形(Circle)和方形(Square)。你希望对这样的类层次结构进行扩展以使其包含颜色,所......
  • java设计模式之适配器模式
    定义将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。在适配器模式中,我们通过增加一个新的适配器类来解决接口不兼容的问题,使得原本没有任何关系的类可以协同工作。......
  • java web 上传文件夹的实现(支持Chrome)
    上传文件夹的思路其实就是将文件夹中所有的文件上传到服务器,上传的时候文件名称要从文件夹目录开始截取,以下图中的目录为例,index.html文件应该以news_1/index.html的路径传到服务器,所有文件上传之后,上传到服务器的文件夹路径是从上传的上传的文件路径截取到文件夹结束。下面详细介......
  • 关于 JavaScript 模块化的描述
    AMD是RequireJS在推广过程中对模块定义的规范化产出,而CMD是SeaJS在推广过程中对模块定义的规范化产出,也就是,RequireJS遵循AMD规范,而Sea.js遵循CMD规范eaJs遵循CMD规范为通用模块规范,RequireJs遵循AMD规范为异步模块规范。CMD依赖就近,AMD依赖前置。//CMDCommonModuleD......
  • Javascript中表达式 "2"+3+4 的值为 "234"
    是左关联,表达式相当于("2"+3)+4根据ES5规范11,6,1节,如果某个操作数是字符串或者能够通过以下步骤转换为字符串的话,+将进行拼接操作。数字+字符串=>(数字).toString()+字符串如:1+'2'=12数字-字符串=>数字-Number(字符串)如:1-'2'=-1+是左连接......