当前位置: 首页 > news >正文

大聪明教你学Java | 深入浅出聊 Stream.parallel()

前言

🍊作者简介: 不肯过江东丶,一个来自二线城市的程序员,致力于用“猥琐”办法解决繁琐问题,让复杂的问题变得通俗易懂。
🍊支持作者: 点赞👍、关注💖、留言💌~

相信各位小伙伴对 Stream 都不陌生,它是 Java 8 及以后版本中引入的一个新特性,用于处理集合数据。Stream 是对集合(Collection)对象功能的增强,与 Lambda 表达式结合,可以提高编程效率、间接性和程序可读性。Stream API 中为我们提供了很多高效且易用的方法,大聪明的好朋友 —— 大明白就对这些方法情有独钟,但是就在前几天,却因为他在项目中使用了 Stream.parallel() 而引发了一个小小的意外情况… …

这里卖个关子😝~ 在说大明白引发的意外情况之前,我们先来一起看看什么是Stream.parallel()

Stream.parallel()

Stream.parallel() 方法用于将流操作转换为并行操作,以便在多个线程上并行执行。并行流是一种可以同时在多个线程上执行操作的流,它将流的元素分割成多个子集,每个子集在不同的线程上独立处理,最后将结果合并。使用 parallel() 方法可以轻松开启并行流处理模式,无需显式管理线程和同步。

List<Integer> numbers = ...; // 假设这里有一个包含大量正整数的List集合numbers.stream() // 创建顺序流.parallel() // 转换为并行流.filter(n -> n % 2 == 0) // 并行流操作 - 过滤List集合中的偶数.map(n -> n * 2) // 并行流操作 - 将过滤出来的偶数×2.forEach(System.out::println); // 并行流操作 - 打印结果

在上面的示例中,parallel() 方法将顺序流转换为并行流,后续的 filter()、map() 和 forEach() 操作将在多个线程上并行执行,从而加速数据处理。我们下面再看看它的底层原理👇

当调用 Stream.parallel() 方法时,它实际上会返回一个新的并行流对象,这个流对象可以在多个线程上并行执行流操作。下面是 Stream.parallel() 方法的大致工作原理:
① 并行流的划分和分治:当我们对并行流进行操作时,Java 会使用 Fork/Join 框架将数据划分成多个小任务,并将这些小任务分配给多个线程来并行执行。这个过程涉及到递归地将大任务分解为小任务,直到小任务足够简单可以直接求解。
② 工作窃取(Work Stealing):Fork/Join 框架采用工作窃取算法来实现任务的调度和执行。在工作窃取的过程中,空闲的线程会主动去其他线程的任务队列中窃取任务执行。这种方式能够充分利用线程资源,提高并行处理的效率。
③合并结果:在并行流的操作中,各个线程会并行地对数据进行处理,最后需要将各个线程的处理结果进行合并,得到最终的结果。这一过程涉及到结果的收集和合并,确保最终的结果是完整且正确的。

这里我们又引申出了一个新的概念 —— Fork/Join 框架。Fork/Join 框架是 Java 7 中引入的用于支持并行计算的框架,是一种并行计算模式,用于解决可以被分解成更小的可并行任务的问题。该模式包含两个关键操作:Fork(分解)和Join(合并)。在 Fork/Join 模式中,原始问题被递归地分解为更小的子问题,直到达到可以并行解决的最小单位。这个过程被称为 Fork。每个子问题可以独立地在不同的处理器上执行,并行地求解部分问题。 一旦所有的子问题都被解决,就会进行 Join 操作。Join 操作将所有子问题的结果合并为最终的解决方案。这种分解和合并的过程可以视为树形结构,其中每个节点代表一个子问题。

Fork/Join 模式最适用于可以自然地分解为多个独立子问题的计算密集型任务。它适用于多核处理器或并行计算环境,其中可以充分利用并行性。Java 平台提供了 Fork/Join 框架,用于实现该模式。它包括了一个线程池(ForkJoinPool)任务(ForkJoinTask) 的概念。任务可以是可分解的子问题,也可以是执行最终计算的任务。通过 ForkJoinPool,可以将任务提交给线程池执行,自动实现任务的分解和合并过程。Fork/Join 模式的优点在于它能够充分利用多核处理器的并行性,提高计算效率。

📌 在这里我们就先对 Fork/Join 框架做一个简单的介绍,后续大聪明会单独出一篇博客对 Fork/Join 框架进行详细的介绍。

咱们言归正传,有些小伙伴看到“线程池(ForkJoinPool)”的时候可能就已经猜测到大明白遇倒的意外情况和线程有关系了。Stream.parallel() 并行流默认使用的是 ForkJoinPool.commonPool() 作为线程池,该线程池默认最大线程数就是 CPU 核数。正是因为大明白对并行流操作的原理不清楚,他在没有配置线程池的情况下,通过并行流做了数据库的大量批量更新操作,于是最大线程数只有 CPU 核数,最终导致在批量更新的时候出现了线程阻塞的情况,从而出现了这个小小的意外。

通过这件事应该也可以给各位小伙伴提个醒,在实际使用时需要慎重考虑并行化带来的影响,并确保线程安全性和并发性。

① 线程安全:并行流并不能保证线程安全性,因此,如果流中的元素是共享资源或操作本身不是线程安全的,你需要确保正确同步或使用线程安全的数据结构。
② 资源消耗:并行流默认使用的线程池大小可能与机器的实际物理核心数相适应,但也可能与其他并发任务争夺系统资源。
③ 结果一致性:并行流并不保证执行的顺序性,也就是说,如果流操作的结果依赖于元素的处理顺序,则不应该使用并行流。
④ 事务处理:在涉及到事务操作时,通常需要避免在并行流中直接处理,如上述例子所示,应当将事务边界放在单独的服务方法内,确保每个线程内的事务独立完成。

小结

本人经验有限,有些地方可能讲的没有特别到位,如果您在阅读的时候想到了什么问题,欢迎在评论区留言,我们后续再一一探讨🙇‍

希望各位小伙伴动动自己可爱的小手,来一波点赞+关注 (✿◡‿◡) 让更多小伙伴看到这篇文章~ 蟹蟹呦(●’◡’●)

如果文章中有错误,欢迎大家留言指正;若您有更好、更独到的理解,欢迎您在留言区留下您的宝贵想法。

你在被打击时,记起你的珍贵,抵抗恶意;
你在迷茫时,坚信你的珍贵,抛开蜚语;
爱你所爱 行你所行 听从你心 无问东西

相关文章:

大聪明教你学Java | 深入浅出聊 Stream.parallel()

前言 &#x1f34a;作者简介&#xff1a; 不肯过江东丶&#xff0c;一个来自二线城市的程序员&#xff0c;致力于用“猥琐”办法解决繁琐问题&#xff0c;让复杂的问题变得通俗易懂。 &#x1f34a;支持作者&#xff1a; 点赞&#x1f44d;、关注&#x1f496;、留言&#x1f4…...

图解大模型分布式并行各种通信原语

背景 在分布式集群上执行大模型任务时候&#xff0c;往往使用到数据并行&#xff0c;流水线并行&#xff0c;张量并行等技术&#xff0c;这些技术本质上也就是对数据进行各种方案的切分&#xff0c;然后放到不同的节点上运算。不同节点在计算的过程中需要对数据分发或者同步等…...

张大哥笔记:下一个风口是什么?

我们经常会问&#xff0c;下一个风口是什么&#xff1f;我们可以大胆预测一下&#xff0c;2024年的风口是什么呢&#xff1f; 40年前&#xff0c;如果你会开车&#xff0c;那就是响当当的铁饭碗&#xff1b; 30年前&#xff0c;如果你会英语和电脑&#xff0c;那也绝对是个人才…...

AI去衣技术中的几何着色:揭秘数字时尚的魔法

在数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;正以前所未有的速度改变我们的生活&#xff0c;从智能家居到自动驾驶汽车&#xff0c;再到个性化医疗。然而&#xff0c;AI的影响远不止于此。它正在重塑我们对艺术、设计和时尚的理解。特别是在数字时尚领域&#…...

Leecode---技巧---只出现一次的数字 / 多数元素

题解&#xff1a; 利用异或运算 a⊕a 0 的性质&#xff0c;可用来消除所有出现了两次的元素&#xff0c;最后剩余的即为所得。 class Solution { public:int singleNumber(vector<int>& nums){// 初始化为0int ans 0;for(int x: nums){// 异或操作ans ^ x;}retur…...

为图片设置经纬度信息

一、java实现 小编看了很多技术博客&#xff0c;但是测试要么下载的jar包中的api和博客对不上&#xff0c;要么就是不对&#xff0c;总之没实现 Java 读取图片信息 java 写入 exif 信息 使用Java读取和修改图片的Exif信息 java获取图片的GPS信息 https://drewnoakes.com/code/e…...

密码和密钥的联系与区别

密码和密钥是两个非常重要的概念&#xff0c;但容易混淆这两者&#xff0c;以下内容介绍了它们的联系和区别&#xff1a; 一、定义 密码&#xff08;Password&#xff09;&#xff0c;在日常语境中&#xff0c;通常指的是个人为了验证自己的身份而设置的一段秘密的字符序列&am…...

C++编程法则365天一天一条(323)main函数执行之前和之后的动作

在C和C程序中&#xff0c;main 函数之前和之后执行的函数是由编译器、链接器和运行时环境共同决定的。以下是一些通常会在这些阶段执行的关键函数&#xff1a; 在 main 函数之前执行的函数 启动代码&#xff08;Start-up Code&#xff09;: 这是由编译器提供的一段代码&#…...

阿里云短信服务使用(Java)

文章目录 一、流程1.打开短信服务2.提交材料申请资质3.资质通过后&#xff0c;申请短信签名并设置短信模板4.右上角设置AccessKey5.充值 二、参考官方文档调用API1.引入maven依赖2.调用API补充 一、流程 1.打开短信服务 登陆注册阿里云 搜索“短信服务”&#xff0c;点击“免…...

C++17之std::void_t

目录 1.std::void_t 的原理 2.std::void_t 的应用 2.1.判断成员存在性 2.1.1.判断嵌套类型定义 2.1.2 判断成员是否存在 2.2 判断表达式是否合法 2.2.1 判断是否支持前置运算符 2.2.3 判断两个类型是否可做加法运算 3.std::void_t 与 std::enable_if 1.std::void_t 的…...

零基础入门篇①⑥ Python可变序列类型--字典

Python从入门到精通系列专栏面向零基础以及需要进阶的读者倾心打造,9.9元订阅即可享受付费专栏权益,一个专栏带你吃透Python,专栏分为零基础入门篇、模块篇、网络爬虫篇、Web开发篇、办公自动化篇、数据分析篇…学习不断,持续更新,火热订阅中🔥专栏限时一个月(5.8~6.8)重…...

C语言面试题1-10

C语言中的内存管理及相关问题探讨 在C语言编程中&#xff0c;内存管理是一个至关重要的概念&#xff0c;掌握内存的分布及其操作不仅能够提高代码效率&#xff0c;还能避免常见的内存泄漏等问题。本文将详细介绍C语言中内存的分布、堆区和栈区的区别、标识符的命名规则、定义和…...

Qt Designer工具如何修改MainWindow窗口的标题

Qt Designer工具如何修改MainWindow窗口的标题 在MainWindow的属性编辑器中选择“windowTitle”后面一栏修改成期望的窗口标题名称即可。 按住“ctrlR”即可查看可视化界面的窗口标题...

车辆前向碰撞预警系统性能要求和测试规程

前言 本文整理《GB/T 33577-2017 智能运输系统-车辆前向碰撞预警系统性能要求和测试规程》国标文件关键信息,FCW系统性能和测试右给深层次的认识。 术语和定义 车辆前向碰撞预警系统 forward vehicle collision warning system自车 subject vehicle(SV)目标车辆 target ve…...

C#实现winform中渲染图的展示

在WinForms中实现图形的渲染展示&#xff0c;可以使用GDI绘图技术。下面是一个简单的示例&#xff0c;演示如何在WinForms中展示一个圆形图形&#xff0c;并根据用户输入的半径动态改变圆的大小&#xff1a; 请在Visual Studio中创建一个WinForms应用程序&#xff0c;并将以下…...

JTS库的讲解及使用

JTS&#xff08;Java Topology Suite&#xff09;是一套用于创建、操作和分析二维几何对象的Java库。JTS提供了丰富的几何操作和分析功能&#xff0c;是GIS&#xff08;地理信息系统&#xff09;应用中的重要工具。以下是JTS库的一些主要功能及其详细使用示例&#xff1a; 1. …...

【C++杂货铺】unordered系列容器

目录 &#x1f308; 前言&#x1f308; &#x1f4c1; unordered系列关联式容器 &#x1f4c1; 底层结构 &#x1f4c2; 哈希概念 &#x1f4c2; 哈希冲突 &#x1f4c2; 哈希函数 &#x1f4c2; 哈希冲突解决 &#x1f4c1; 模拟实现 &#x1f4c1; 总结 &#x1f308; 前…...

模板-初阶

引言&#xff1a; 在C&#xff0c;我们已经学过了函数重载&#xff0c;这使得同名函数具有多个功能。但是还有一种更省力的方法&#xff1a;采用模板。 本文主要介绍以下内容 1. 泛型编程 2. 函数模板 3. 类模板 1.泛型编程 在将这一部分之前&#xff0c;通过一个故事引…...

重载运算符C++---学习笔记

一、笔记 1. 重载运算符基础知识 重载运算符进行的运算和普通数的加减运算不同之处在于重载运算符的操作数为一个一个自定义的对象&#xff0c;所以相应的要对普通的运算符如-*%/的调用方法进行重写&#xff0c;重载的本质还是函数调用 2. 重载运算符的语法 重载运算符的语…...

SpringMVC枚举类型字段处理

在日常的项目开发中经常会遇到一些取值范围固定的字段&#xff0c;例如性别、证件类型、会员等级等&#xff0c;此时我们可以利用枚举来最大程度减少字段的乱定义&#xff0c;统一管理枚举的值。 SpringMVC中对于枚举也有默认的处理策略&#xff1a; 对于RequestParam&#xf…...

YOLOv10镜像作品集:高清图像目标检测惊艳案例分享

YOLOv10镜像作品集&#xff1a;高清图像目标检测惊艳案例分享 1. 引言&#xff1a;YOLOv10带来的视觉革命 在计算机视觉领域&#xff0c;目标检测技术正经历着前所未有的变革。YOLOv10作为最新一代的目标检测模型&#xff0c;以其无与伦比的速度和精度重新定义了实时检测的标…...

保姆级教程:用OpenAI Whisper给视频自动生成字幕(附Python代码)

视频创作者必备&#xff1a;用Whisper打造高效字幕工作流 每次剪辑视频最头疼的就是加字幕&#xff1f;作为过来人&#xff0c;我完全理解那种对着时间轴逐帧调整的痛苦。直到发现Whisper这个神器&#xff0c;我的工作效率直接翻了三倍。今天就把这套全自动字幕生成方案完整分享…...

Android USB串口通信终极指南:智能家居物联网项目实战

Android USB串口通信终极指南&#xff1a;智能家居物联网项目实战 【免费下载链接】usb-serial-for-android Android USB host serial driver library for CDC, FTDI, Arduino and other devices. 项目地址: https://gitcode.com/gh_mirrors/us/usb-serial-for-android …...

网络基础知识整理(精简通用版)20260331-001篇

文章目录 网络基础知识整理(精简通用版) 一、网络基本概念 二、网络拓扑结构 三、OSI 七层模型(核心参考) 四、TCP/IP 模型(实际互联网标准) 五、IP 地址基础 六、传输层协议(TCP vs UDP) TCP(传输控制协议) UDP(用户数据报协议) 七、常见网络协议与端口 八、网络设…...

AMD Ryzen硬件调试终极指南:3大突破性能优化秘籍揭秘

AMD Ryzen硬件调试终极指南&#xff1a;3大突破性能优化秘籍揭秘 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://git…...

nlp_gte_sentence-embedding_chinese-large保姆级教程:免配置镜像启动+Web界面使用详解

nlp_gte_sentence-embedding_chinese-large保姆级教程&#xff1a;免配置镜像启动Web界面使用详解 你是不是经常遇到这样的问题&#xff1a;手里有一堆文档&#xff0c;想快速找到和某个问题最相关的内容&#xff0c;却只能靠关键词搜索&#xff0c;结果要么漏掉&#xff0c;要…...

Ubuntu系统通过命令行与GUI配置以太网固定IPv4地址全指南

1. 为什么需要固定IP地址&#xff1f; 在日常使用Ubuntu系统时&#xff0c;大多数情况下我们都会选择自动获取IP地址&#xff08;DHCP&#xff09;。这种方式简单方便&#xff0c;特别适合家庭网络环境。但如果你正在搭建服务器、进行网络调试&#xff0c;或者需要远程访问这台…...

嵌入式SD卡文件处理轻量级工具库LC_SDTools

1. LC_SDTools 库概述LC_SDTools 是一个面向嵌入式 SD 卡文件系统应用的轻量级工具库&#xff0c;专为解决裸机或 RTOS 环境下 SD 卡文件操作中高频缺失的基础能力而设计。其核心定位并非替代 FatFs、LittleFS 或 ChibiOS FAT 模块等完整文件系统栈&#xff0c;而是作为上层应用…...

Kubernetes + LLM 实战:如何用 Gateway API Inference Extension 优化推理服务(附避坑指南)

Kubernetes LLM 实战&#xff1a;Gateway API Inference Extension 深度优化指南 在当今AI技术迅猛发展的背景下&#xff0c;大语言模型(LLM)已成为企业智能化转型的核心驱动力。然而&#xff0c;当这些复杂的模型需要部署到生产环境时&#xff0c;传统的Kubernetes路由方案往…...

3步搞定开源工具ESLyric歌词源配置指南

3步搞定开源工具ESLyric歌词源配置指南 【免费下载链接】ESLyric-LyricsSource Advanced lyrics source for ESLyric in foobar2000 项目地址: https://gitcode.com/gh_mirrors/es/ESLyric-LyricsSource 在数字音乐播放体验中&#xff0c;歌词显示的精准度与丰富度直接影…...