JavaOne 2016次日—— \"并行编程思想\"

在JavaOne大会上,Oracle的Stuart Marks和Brian Goetz深入探讨了并行编程的概念及其实现方法。他们通过Stream API解释了并行处理,演示了如何使用Stream简化常见编程任务,如将字符串数组转换为大写、按关键字分割列表等。此外,还讨论了并行计算的优势和挑战,包括并行计算带来的额外开销。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JavaOne次日,视频直播涵盖了四个会议室。这些会议的视频链接在本文末尾给出。

\\

InfoQ参与了会议《并行编程思想(Thinking in Parallel)》,本文主要讨论该话题(视频链接见文末)。该话题的演讲人是来自Oracle的Stuart Marks和Brian Goetz。二人组完美的通过流API(streams)解释了并行处理,其中Marks着重介绍了为什么要使用Stream API,而Goetz着重介绍了为什么要使用并行化。

\\

Marks的演讲从一个将字符串数组转换成大写的示例开始,同时展示了常规实现和Stream实现。

\\

常规实现使用一个for循环,内容如下:

\\

f97b1c69399551775ba70d3b71bbb631.png

\\

这里输入数组从左往右顺序处理,但是主要运算逻辑仅仅是“转换成大写”,且每个字符串运算都相互独立。另外,数组中的数据可以以任何顺序处理,或者是并行处理。那么,如果使用Stream方式会怎样呢?

\\

4499ba9972cf0ab84f476582bda3a588.png

\\

在使用Stream方式的示例中,输入数组被映射成大写,然后被重组成数组。输入和输出数组中的内容无需保证顺序,整个数组都被转换成大写。

\\

Marks声称Stream版本更好,因为它有更高级别的抽象、计算的独立性和聚合性。

\\

bc64b2e9148946b1cd216d36e26c3ffe.png

\\

下一个示例演示的是通过指定关键字将一个列表分割,内容如下:

\\

e0d29b541a28d91bf27d698dbfc395a7.png

\\

Marks指出subList方法参数为原始列表索引值,为了完成这个需求,算法必须在“#”处分割。为了便于理解,Marks在“#”处放置了黑条来表示子列表的边界,然后将每个边界切分并合成创建新的子列表边界。示意图如下:

\\

b0d07d62c59529779a7a294dc66bc2ce.png

\\

使用传统方式实现这个算法:

\\

a8470957e895fd450edb5126e26a2f37.png

\\

以上实现有一些额外的复杂度,增加了理解成本,例如:start = cur + 1;语句和在for循环之外调用result.add方法。对此,Marks的观点是:

\\

d68678d821b83db8375bb3fd2e04c71e.png

\\

Marks对比了Stream实现,重新审视问题,我们唯一关心的是索引。因此,不同于之前的for循环,这里通过Stream来检查索引。由于断言和结果分割运算相互独立,我们可以针对每个元素做断言验证,并且这些验证都可以独立计算。上面描述的结果代码(消除了数组复制而改成追加到数组之后)大致如下:

\\

0da9638333b0d86bb24fa36dd49a4664.png

\\

Marks总结了他的观点:Stream实现更加清晰。

\\

a26b9bfc79298b3b45c215f492687cc2.png

\\

随后,Goetz补充了Marks的演讲主题,考虑了并行计算的优势和劣势。他从下面这页演示文稿开始讨论并行化,指出并行化是消耗更多资源和更快得到结果的权衡。

\\

2fc1040f2bb72953aea516bf45806075.png

\\

Goetz强调,并行计算总是会增加更多的并行化事务,例如划分工作,管理和协调任务以及他们的结果。所以,如果计算任务能够被成功的并行化,该任务本身应该是可并行化并且有优秀的并行计算框架(例如fork-join库)。最后,还应该有足够的数据来并行的处理。随后,Goetz提供了一些可以有效进行并行化的示例,并向听众展示了如何分而治之:

\\

efde2e3449f7f328432cdec97de352c4.png

\\

Goetz强调所有的并行解决方案实质上都看起来像上面分而治之的思想:将问题划分以避免同步开销。对于一个高效的并行算法,问题应该尽早的被分割。Goetz提供了一个示例,展示了并行的对一个数组进行求和,并给出了一些性能考量:

\\

6ca81fbebdf9291ea741444df261431f.png

\\

最后,Goetz讨论了并行Stream性能。Stream容易被并行化,但是不是所有源数据都适合并行处理。

\\
\

基于数组的源数据是最佳的。

\
\\

根据Goetz的描述,“NQ模型”是一个简单的模型,一个用来计算并行化提速的经验法则:

\\

2bd4f47c8c2dd6ad88d3eb02339365ff.png

\\

Goetz探讨了“源数据分割效率”,提到了数组由于其底层实现方式,它的分割非常均匀且低成本。另外需要记得一些管道操作会依赖数据顺序,例如“限制10项”操作显然是按顺序应用到前10项。另一个需要考虑的的是有时归并操作可能成本会很高。

\\

Goetz总结了整个会议主题:

\\

1d1c78c480cbdd00544e820ac83dd2a7.png

\\

相关链接:

\\

会议室4

\\

会议室6

\\

Cyrill Magnin II/III

\\

Embarcadero

\\

查看英文原文:JavaOne 2016 - Day 2 \"Thinking in Parallel\"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值