在Java EE容器中使用Java 8并行流是否被反对?

38
鉴于在Java EE容器中生成线程是不被鼓励的,那么在Java EE内部使用可能会生成线程的Java 8并行流是否也不被鼓励呢?请参考此处此处

3
@RobertHarvey 在JavaEE中使用线程是不被鼓励的,Java 8引入了并行流(在后台使用线程)。我们能否在JavaEE中使用并行流,或者也被不鼓励?我认为这是一个公正而有趣的问题。我稍微改了一下措辞 - 可能还可以进一步改进。 - assylias
3
@RobertHarvey?线程被不少规格说明书所禁止或不鼓励,因为线程应该由应用服务器自行管理(请参考右侧的第一个链接)。使用并行流可能会“破坏”一些东西——也可能不会。这就是问题所在。根据规格说明书,它可能会或可能不会“破坏”某些东西:这不是一个观点。只是我的个人见解。你决定吧——我今天就到这儿!;-)(在做出决定后,请随意删除杂音) - assylias
14
是的,这会破坏一些东西。例如,安全和事务上下文是由ThreadLocal变量处理的。而且JPA实体不是线程安全的。因此,无论如何启动线程,都将破坏安全性和事务处理。Java EE 7规范引入了特殊执行器,如果您想在Java EE环境中执行线程任务,则应使用它们。但Java EE落后于Java SE,尚未准备好使用并行流。 - JB Nizet
2
这是一个很好的问题,已经被Java EE工程师回答了。他们将所有并行操作转换为顺序处理。您可以在lambda-dev@openjdk.java.net邮件列表中找到讨论。 - edharned
3
@Shorn:http://mail.openjdk.java.net/pipermail/lambda-dev/2013-April/009334.html - JB Nizet
显示剩余7条评论
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的源代码,并没有一个使用、或的地方。

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


通过将java.util.concurrent.ForkJoinPool.common.parallelism系统属性设置为1,可以以便携的方式实现优雅降级吗? - areus


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接