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

平行流如何“知道”使用封闭的ForkJoinpool?

卢志强
2023-03-14

在Java8中,可以设置一个自定义forkJoinpool,由并行流而不是公共池使用。

forkJoinPool.submit(() -> list.parallelStream().forEach(x ->{...} ))

我的问题是技术上是如何发生的
流在任何方面都不知道它已提交到自定义forkJoinpool,并且无法直接访问它。那么,最终如何使用正确的线程来处理流的任务呢?

我试着看源代码,但没有用。我的最佳猜测是在提交时的某个点设置了一些threadLocal变量,然后流在稍后使用。如果是这样,为什么语言开发人员会选择这样一种方式来实现行为,而不是(比如)将池注入流中的依赖关系?

谢谢!

共有2个答案

丌官向荣
2023-03-14

java。util。流动前肢手术。ForEachOp#evaluateParallel方法调用invoke()

@Override
public <S> Void evaluateParallel(PipelineHelper<T> helper,
                                 Spliterator<S> spliterator) {
    if (ordered)
        new ForEachOrderedTask<>(helper, spliterator, this).invoke();
    else
        new ForEachTask<>(helper, spliterator, helper.wrapSink(this)).invoke();
    return null;
}

它依次调用java。util。同时发生的ForkJoinTask#doInvoke

private int doInvoke() {
    int s; Thread t; ForkJoinWorkerThread wt;
    return (s = doExec()) < 0 ? s :
        ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
        (wt = (ForkJoinWorkerThread)t).pool.
        awaitJoin(wt.workQueue, this, 0L) :
        externalAwaitDone();
}

如上面的方法所示,它使用thread查找当前线程。currentThread()

然后使用。池字段,如(wt=(ForkJoinWorkerThread)t中所示。池,它提供此线程运行的当前池:

public class ForkJoinWorkerThread extends Thread {

    final ForkJoinPool pool;                // the pool this thread works in
叶鸿
2023-03-14

从我所读的代码中,决策仅基于触发计算的初始线程,在方法ForkJoinTask::fok中,从字面上对触发此的线程进行检查(也在其留档中):

Thread.currentThread()) instanceof ForkJoinWorkerThread

因此,如果ForkJoinWorkerThread的一个实例启动了此任务(这是通过自定义ForkJoinPool可以得到的),请使用该池中已经存在且该任务在其中运行的任何资源;否则(如果它是一个不同的线程,而不是ForkJoinWorkerThread的实例),请使用:

ForkJoinPool.common.externalPush(this); 

同样有趣的是,ForkJoinWorkerThread实际上是一个public类,因此您可以在它的实例中启动计算,但仍然使用不同的池;虽然我没有试过。

 类似资料:
  • 在Java8中,可以设置一个定制的forkJoinPool供并行流使用,而不是公共池。 我的问题是它在技术上是如何发生的? 流以任何方式都不知道它被提交给了自定义的forkJoinpool并且没有直接访问它的权限。那么最终如何使用正确的线程来处理流的任务呢? 我试着看源代码,但没有用。我的最佳猜测是在提交时的某个点设置了某个threadLocal变量,然后在稍后由流使用。如果是这样的话,为什么语言

  • 问题内容: 我正在实现一个小型TCP服务器。我怎么知道我的一位客户是否关门?我应该只是尝试读取或写入并检查是否为零? 问题答案: 该线程“ 的最佳方式可靠地检测TCP连接被关闭 ”,使用了“ ”(也可见于或或许多其他情况下): 为了检测超时,建议: 更新2019:tuxedo25在评论中提到: 在Go 1.7+中,零字节读取立即返回,并且永远不会返回错误。 您必须读取至少一个字节。 参见commi

  • 本文向大家介绍如何知道对象是否用JavaScript密封?,包括了如何知道对象是否用JavaScript密封?的使用技巧和注意事项,需要的朋友参考一下 Object.isSealed()是用于查找对象是否在javascript中密封的方法。此方法给出布尔输出。  如果满足以下条件,则将对象密封。 1)不可扩展。 2)其属性应不可配置。 语法 参数  -Object.isSealed()将对象作为参

  • 问题内容: 我在Linux Ubuntu服务器中搜索php.ini文件所在的路径,并且在执行命令时发现很多php.ini 。那么如何从php.ini所在的php脚本网页中确切地知道呢? 问题答案: 您可以使用php_ini_loaded_file() 取自php.net: 您可能还需要检查php_ini_scanned_files() 另外,您应该注意,如果从CLI运行PHP脚本,则有可能使用与服

  • 我想用java写一个传输文件套接字程序。但我有问题,如何取消时传输文件。 当我在客户端关闭inputstream时,服务器如何知道它关闭了outputstream。 这是我的代码:客户 ...... 服务器 ...... 但当我关闭inputstream时没有显示任何内容

  • 我想采取以下方法: 并使用Streams api更新它。这是我到目前为止得到的: 有没有办法在不流式传输两次(第二次获得计数)的情况下做到这一点?