【问题标题】:ParallelStream queue task in CommonPool rather than the custom poolCommonPool 而非自定义池中的 ParallelStream 队列任务
【发布时间】:2018-10-16 13:07:23
【问题描述】:

我想为 parallelStream 使用自定义 ThreadPool。原因是我想在任务中使用 MDCContext 。这是我编写的使用自定义线程池的代码:

final ExecutorService mdcPool = MDCExecutors.newCachedThreadPool();
mdcPool.submit(() -> ruleset.getOperationList().parallelStream().forEach(operation -> {
                log.info("Sample log line");
});

当 MDC 上下文没有被复制到任务时,我查看了日志。这些是我找到的日志。第一个日志在“(pool-16-thread-1)”中执行,但其他任务正在“ForkJoinPool.commonPool-worker”上执行。第一个日志也有 MdcContextID。但由于我使用自定义线程池提交任务,所有任务都应该在自定义线程池中执行。

16 Oct 2018 12:46:58,298 [INFO] 8fcfa6ee-d141-11e8-b84a-7da6cd73aa0b (pool-16-thread-1) com.amazon.rss.activity.business.VariablesEvaluator: Sample log line
16 Oct 2018 12:46:58,298 [INFO]  (ForkJoinPool.commonPool-worker-11) com.amazon.rss.activity.business.VariablesEvaluator: Sample log line
16 Oct 2018 12:46:58,298 [INFO]  (ForkJoinPool.commonPool-worker-4) com.amazon.rss.activity.business.VariablesEvaluator: Sample log line
16 Oct 2018 12:46:58,298 [INFO]  (ForkJoinPool.commonPool-worker-13) com.amazon.rss.activity.business.VariablesEvaluator: Sample log line
16 Oct 2018 12:46:58,298 [INFO]  (ForkJoinPool.commonPool-worker-9) com.amazon.rss.activity.business.VariablesEvaluator: Sample log line
16 Oct 2018 12:46:58,299 [INFO]  (ForkJoinPool.commonPool-worker-2) com.amazon.rss.activity.business.VariablesEvaluator: Sample log line
16 Oct 2018 12:46:58,299 [INFO]  (ForkJoinPool.commonPool-worker-15) com.amazon.rss.activity.business.VariablesEvaluator: Sample log line

这是应该发生的还是我错过了什么?

【问题讨论】:

    标签: java java-8 threadpool mdc forkjoinpool


    【解决方案1】:

    不支持在自定义线程池中运行并行流。当操作在不同 Fork/Join 池的工作线程中启动时,它碰巧在不同的 Fork/Join 池中执行,但这似乎不是计划中的功能,因为 Stream实现代码在某些操作中仍会在内部使用公共池的工件。

    在您的情况下,MDCExecutors.newCachedThreadPool() 返回的 ExecutorService 似乎不是 Fork/Join 池,因此它根本没有表现出这种未记录的行为。

    有一个关于更多线程控制的功能请求,JDK-8032512。它是开放的,据我所知,没有太多活动。

    【讨论】:

    • 我现在很困惑:| this 呢?或者你的意思是它必须是另一个ForkJoinPool
    • @Eugene 正如所说,它碰巧以这种方式工作(当自定义池是 Fork/Join 池时),作为实现细节的结果,而不是计划特征。与this answer 相比,Stuart Marks 明确指出不能保证此技巧有效,并且还描述了我所说的“Stream 实现代码仍将在内部使用公共池的工件”的问题之一。
    • 这似乎对我(几乎直接)影响很大。我写了几个地方,我使用自定义并行流在单独的 ForkJoinPool 中运行,因为我不想被阻止以防其他人使用默认的,看来我需要重新考虑代码,但我可能会没有替代品。谢谢你的评论
    猜你喜欢
    • 1970-01-01
    • 2023-03-19
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多