首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从List<Long>的RecursiveTask中收集ForkJoinPool结果

从List<Long>的RecursiveTask中收集ForkJoinPool结果
EN

Stack Overflow用户
提问于 2019-06-24 18:11:10
回答 1查看 453关注 0票数 0

我们需要在一个分支池中将一个素数计算拆分成多个递归任务。

我们有一个素数列表和一个workloadSize,比如5,所以如果我们想计算50的素因数,我们把所有的素数都设为25,然后计算素因数。workloadSize是单个递归任务将处理的质数的数量。

我做了什么:

代码语言:javascript
复制
Long[] workLoad = new Long[primes.size()];
workLoad = primes.toArray(workLoad);

pool = new ForkJoinPool();
ForkJoinWorker worker = new ForkJoinWorker(workLoad, q, partitionSize, 0);
pool.execute(worker);

resultList =  worker.invoke();

workLoad =所有质数的数组。

Q=我们要计算素因数的数字。

ForkJoinWorker扩展了RecursiveTask>

在递归任务中,我查看workLoadSize是否大于获得的素数组,如果大于,则创建一个新的

代码语言:javascript
复制
ForkJoinWorker f = new ForkJoinWorker(..);
f.fork();
List<Long> results = calcFactors(...);
results.addAll(f.join);
return results;

我是不是完全搞错了?我总是得到一个并发异常和堆栈溢出。我想我没有正确地连接递归任务,因为它总是导致堆栈溢出。

EN

回答 1

Stack Overflow用户

发布于 2019-06-24 21:39:12

完整的堆栈跟踪和更完整的代码示例应该有助于澄清发生了什么。但是,在您所展示的代码中,有几点是很突出的。

调用主任务

在您的示例中,您需要

代码语言:javascript
复制
pool.execute(worker);
resultList =  worker.invoke();

这不是它应该工作的方式。

调用"execute“会分派任务,这很好,但它不会等待任务完成。因此,您只是启动了一个计算,在其完成或结果时没有句柄。

自己调用invoke不是你通常会做的事情,你应该让pool自己调用这个方法。因为它将在调用线程中启动任务的执行,而不需要任何池的支持。因此,如果你以不合逻辑的顺序执行join,你甚至可能会死锁自己。

调用RecursiveTask<T>的“预定”方式是调用pool.invoke(task),它将返回T (计算结果)或pool.submit(task),后者将返回Future

在任务之间共享状态

任务中的这段代码可能会有问题:

代码语言:javascript
复制
List<Long> results = calcFactors(...);
results.addAll(f.join);

如果calcFactors创建自己的List来返回,它就会起作用。但是,如果这个列表在任务之间共享,这意味着多个任务(和线程)可以在同一实例上执行addAll,这只有在列表能够支持它的情况下才能工作(我认为JDK中唯一并发的ListCopyOnWriteArrayList)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56734350

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档