当前位置: 首页 > 知识库问答 >
问题:

Java parallelStream()带有自定义池,调用方工作被窃取?

孟豪
2023-03-14

通常,当使用Java8的parallelStream()时,结果是通过默认的公共fork-join池(即forkjoinpool.commonpool())执行。

然而,如果一个人的工作远离CPU的限制,例如,可能在很长时间内等待IO的工作,那么这显然是不可取的。在这种情况下,您将希望使用一个单独的池,根据其他标准(例如,任务可能实际使用CPU的时间的多少)进行大小调整。

没有明显的方法让parallelStream()使用不同的池,但这里详细介绍了一种方法。

不幸的是,这种方法需要对来自fork-join池线程的并行流调用终端操作。这样做的缺点是,如果target-fork联接池完全忙于现有工作,则整个执行将在完全不做任何事情的情况下等待它。因此,池可能成为比单线程执行更糟糕的瓶颈。相反,当以“正常”方式使用parallelStream()时,forkJoinPool.common.ExternalHelpComplete()或forkJoinPool.common.TryExternalUnpush()用于让池外部的调用线程帮助处理。

有没有人知道一种方法,既让parallelStream()使用非默认的fork-join池,又让fork-join池外部的调用线程帮助处理这项工作(但不是fork-join池的其余工作)?

共有1个答案

司寇善
2023-03-14

您可以在池上使用awaitquiescess来提供帮助。但是,您不能选择要帮助的任务,它只会从池中获取下一个挂起的任务,因此,如果有更多挂起的任务,您可能会在得到自己的任务之前执行这些任务。

ForkJoinPool forkJoinPool = new ForkJoinPool(1);
// make all threads busy:
forkJoinPool.submit(() -> LockSupport.parkNanos(Long.MAX_VALUE));
// submit our task (may contain your stream operation)
ForkJoinTask<Thread> task = forkJoinPool.submit(() -> Thread.currentThread());
// help out
while(!task.isDone()) // use zero timeout to execute one task only
    forkJoinPool.awaitQuiescence(0, TimeUnit.NANOSECONDS);
System.out.println(Thread.currentThread()==task.get());

将打印true

鉴于

ForkJoinPool forkJoinPool = new ForkJoinPool(1);
// make all threads busy:
forkJoinPool.submit(() -> LockSupport.parkNanos(Long.MAX_VALUE));
// overload:
forkJoinPool.submit(() -> LockSupport.parkNanos(Long.MAX_VALUE));
// submit our task (may contain your stream operation)
ForkJoinTask<Thread> task = forkJoinPool.submit(() -> Thread.currentThread());
// help out
while(!task.isDone())
    forkJoinPool.awaitQuiescence(0, TimeUnit.NANOSECONDS);
System.out.println(Thread.currentThread()==task.get());

但请注意,fork/join框架和streamAPI之间的整个关系无论如何都是一个实现细节。

 类似资料:
  • 我看了堆栈交换和Spring示例网站上的每个示例,一切似乎都应该有效。我一定错过了一些简单的东西 我有一个自定义注释,理想情况下,如果类被注释,我希望将其应用于类的所有方法,或者应用于任何注释的方法。以下是方面、测试和代码: 注释 方面 测验 后果 链接 实际来源

  • 在我的项目中,我正在构建一个Java的执行框架,它接收来自客户端的工作请求。工作(大小不同)被分解为一组任务,然后排队等待处理。有单独的队列来处理每种类型的任务,每个队列都与一个ThreadPool相关联。ThreadPools的配置方式使引擎的整体性能达到最佳。 这种设计有助于我们有效地平衡请求的负载,大型请求不会占用系统资源。然而,当一些队列为空并且它们各自的线程池闲置时,该解决方案有时会变得

  • 我正在寻找Spring Boot maven应用程序的工作示例,没有引用spring-boot-starter-parent作为父POM。 我在Spring Boot docs-http://Docs.Spring.io/spring-boot/Docs/1.0.1.release/reference/htmlsingle/#using-boot-maven-your-own-parent中找到了

  • 问题内容: 我正在尝试使用Process对象在python中使用工作池。每个工作人员(一个流程)进行一些初始化(花费很短的时间),传递一系列的工作(最好使用),然后返回一些信息。除此之外,没有必要进行任何沟通。但是,我似乎无法弄清楚如何使用map()使用工作人员的函数。 是代替工作队列吗,还是可以使用? 问题答案: 我建议您为此使用队列。 现在您可以开始一堆这些工作,所有工作都从一个队列开始 这种

  • 我正在尝试使用基于自定义列表的自定义创建一个自定义。 自定义对象是名为的类名,其中包含一些用于消息内容、收件人、时间戳和状态(读取、发送等)的字段。 在看了这个问题:用FXML在JavaFX中定制ListView之后,我成功地做到了: null 现在,ConversationCell类: 我不能显示ConversationCellController,但我所能说的是,这是我(在其构造函数中)加载设

  • 我在textInputEditText中使用textInputLayout,我必须为editText设置背景,以实现editText的边框视图。但是当我调用textInputLayout上的setError()时,整个editText颜色将变为红色。但我只想更改错误文本的颜色,而不是整个视图。 设置前错误: 请帮帮我,我做错了什么?