37

鉴于不鼓励在 Java EE 容器中生成线程。在 Java EE 中使用可能产生线程的Java 8 并行流是否也会被劝阻?

4

2 回答 2

17

注意,优雅降级到单线程是不可用的。我还认为这是因为 Shorn 的回答和邮件列表讨论,但我发现不是在研究这个问题时。该机制不在 Java EE 7 规范中,也不在 glassfish 4.1 中。即使另一个容器这样做,它也不是便携式的。

您可以通过调用以下方法对此进行测试:

@Singleton
public class SomeSingleton {
    public void fireStream() {
        IntStream.range(0, 32)
            .parallel()
            .mapToObj(i -> String.format("Task %d on thread %s", 
                i, Thread.currentThread().getName()))
            .forEach(System.out::println);
    }
}

你会得到类似的东西:

Info:   Task 20 on thread http-listener-1(4)
Info:   Task 10 on thread ForkJoinPool.commonPool-worker-3
Info:   Task 28 on thread ForkJoinPool.commonPool-worker-0
...

我还检查了 glassfish 4.1.1 源代码,并且没有单独使用ForkJoinPool,ForkJoinWorkerThreadFactoryForkJoinWorkerThread.

该机制可以添加到 EE 8 中,因为许多框架将利用 jdk8 功能,但我不知道它是否是规范的一部分。

于 2016-04-02T16:25:26.123 回答
13

编辑 请参阅来自的替代答案andrepnh。以下可能是计划,但在实践中似乎并没有这样发展。


我从评论中提到的lambda-dev 邮件列表讨论中阅读它的方式:它并不气馁产生线程的方式 - 但在 Java EE 上下文中不会为您做任何事情。

从链接的讨论:

Java EE 并发人员已经讨论过这个问题,目前的结果是,当从 EE 容器内运行时,FJP 将优雅地降级为单线程(甚至是调用者上下文)执行

因此,您可以在两种上下文中运行的过程或库中安全地使用并行流。当它在 SE 环境中运行时,它会使用神奇的并行恶作剧——但当它在 EE 环境中运行时,它会优雅地降级为串行执行。

注意:上面引用的短语是将来时 - 有人引用了一些权威文档吗?

于 2014-04-09T03:03:37.637 回答