假设给定整数a
和b
,这样就形成了一个感兴趣的[a,b]
中整数的范围,该范围可以跨越10^9
整数,我想对给定函数f : N -> N
的所有整数a <= n <= b
的值求和,该范围非常大,所以我想使用多线程来完成。
不太正式地说,我想并行化以下代码:
long sum = 0;
for (long n = a ; n <= b ; n++)
sum += f(n);
System.out.println(sum);
理想情况下(至少在我看来),这个范围将在处理器可用的线程数上平均划分(假设f(n)
对于范围内的每个n
具有几乎相同的复杂度和运行时间)。这些值是完全独立的,并且f
实际上可以是任何函数。例如,它可以输出数字的位数之和。但它真的可以是任何东西,这只是一个例子。
在Java中,是否有一种使用多线程的通用方法可以做到这一点?
4条答案
按热度按时间zxlwwiss1#
并行流
这个特殊的用例非常适合并行流。请参见tutorial by Oracle。
java.util.stream.LongStream
类用于64位long
整数流。像这样实现:
参见类似代码run at Ideone.com。
t5zmwmid2#
您可能想了解一下fork/join framework;这是一种将任务拆分为许多小的独立任务然后将它们组合在一起的原则的通用方法,并为您提供了有关如何拆分线程的所有控制。
或者,您可以使用流API的
parallel()
方法,但请注意,该方法并不能解释或保证它是如何工作的。您无法控制哪个方面被并行化,也无法控制所涉及的线程数量。对于一般情况,您也可以使用它,但作为一项规则,如果“我最好并行写这个,否则会太慢”是相关的,那么你需要一些保证和一些控制。这里是oracle's tutorial/explanation on parallel streams。对于这个特定的情况,它看起来或多或少会做你想要的(例如,如果您尝试将其应用到的流是Files.lines
所提供的,则这会变得棘手--其中并行性可能由于其应用的位置与瓶颈所在的位置而受到阻碍)。z8dt9xmd3#
RecursiveTask
适用于此类问题,线程将由ForkJoinPool
管理。一般的想法是将问题分解为更短的子问题,直到单个线程能够自己管理给定的子问题。
像这样使用它:
ef1yzkbh4#
1.创建你的sum类(编辑'f'函数到你的函数):
1.主要内容: