gpt4 book ai didi

java - ForkJoinTask 完成处理程序

转载 作者:行者123 更新时间:2023-12-01 14:10:20 28 4
gpt4 key购买 nike

我有一个长时间运行的计算,已与 Java's ForkJoinTask 分开.

Java's FutureTask提供了一个模板方法done()Overriding this method allows for "registering a completion handler"

是否可以为ForkJoinTask注册完成处理程序?

我这样问是因为我不想在我的应用程序中出现阻塞线程 - 但是一旦我通过调用 result = ForkJoinPool.invoke(myForkJoinTask) 检索计算结果,我的应用程序就会出现阻塞线程result = ForkJoinPool.submit(myForkJoinTask).get()

最佳答案

我认为你的意思是“无锁”编程 http://en.wikipedia.org/wiki/Non-blocking_algorithm ?虽然 FutureTask.get() 可能会阻塞当前线程(从而使 CPU 空闲),但 ForkJoinTask.get() (或 join)会尝试保持 CPU 忙碌。

如果您能够将问题分解为许多小问题(ForkJoinTask),那么这种方法会很有效。如果一个 FJTask 正在内部等待另一任务的结果,但该任务尚未准备好,则 ForkJoinTask 会尝试从其 ForkJoinPool 中获取一些其他工作(任务),并同时执行该任务。

直到所有任务都受 CPU 限制之前,它都可以正常工作:所有 CPU 都保持忙碌。如果您的任何任务等待某些外部事件(即向火星漫游者发送 REST 调用),它就不起作用。此外,问题应该形成 DAG ,否则可能会陷入僵局。但是,除非您仅将之前 fork 的任务加入到同一个任务中,否则它会很好地工作。如果您加入最后 fork 的任务就更好了。

因此,在任务内/之间调用 get() 或 join() 并不算太糟糕。

您提到了一个完成处理程序来解决该问题。如果您自己实现 ForkJoinTask,您可以查看 RecursiveTask 甚至 RecursiveAction。您将实现compute(),并且可以轻松地将每个任务的结果转发到compute()函数末尾的某个收集器,而不是返回它。

但是你必须考虑你的收集器将被同时调用!要添加值或计算完成计数,请查看 java.util.concurrent.atomic 。避免使用同步块(synchronized block)。否则,您的所有任务都必须等待这个单一瓶颈,并且只有一个 CPU 继续工作。

我认为传播结果比返回结果涉及更多问题(因为 FJPool 处理这个问题)。此外,很难决定(以及与外界沟通)最终结果何时完成。

关于java - ForkJoinTask 完成处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18565264/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com