我知道在JavaEE应用程序中分离线程是一个很大的禁忌。但是,我有一个应用程序是Java's fork/join mechanism的完美候选者。但是,由于不应该在应用程序中创建线程,有没有办法在我的EJB中使用它?我知道在WebSphere应用程序中,异步bean功能提供了这一功能。但是,我的应用程序部署在JBoss EAP 6.1上,所以这不是一个选项。
在JavaEE应用程序中是否有“合法”的方法来实现fork / join?
答案 0 :(得分:6)
现在最好的答案是Java EE 7规范中的Concurrency Utils API。您有ManagedExecutors和ManagedThreadPools。由于这些托管线程功能和托管任务由应用程序服务器控制,因此确保您的fork连接计算使用这些资源,然后您可以确保线程被包含而不是孤立。
最后,您可能必须编写一个“Managed”的ForkJoinPool版本才能获得最佳解决方案。但是,它应该是可能的,因为作为第一步,将使用托管版本替换线程池执行程序。
PS:Java SE 8必须在发布Java SE 8时解决此问题!
答案 1 :(得分:3)
JBoss EAP 6.1实际上也支持异步EJB。但是,当您不需要等待子任务的结果时,AFAIK异步EJB才真正帮助您(例如,您只需要fork部分,而不是连接部分)。
如果您使用java.util.concurrent.ForkJoinPool
,那么在Java EE中没有合法的方式使用它,Java EE 7 / JSR-236没有帮助(我向EG提出了这一点,但他们不能打扰)。 ForkJoinPool
spwans线程是非法的,来自EE 7 / JSR-236的ManagedThreadFactory
不是ForkJoinWorkerThreadFactory
。
在JDK 8中有一个默认的ForkJoinPool
,它可以配置为不生成任何线程并在调用程序线程中运行所有内容(可能通过"java.util.concurrent.ForkJoinPool.common.parallelism"
系统属性)。这使它合法,但不会给你任何并行性。
更一般地说,fork连接任务应该是计算绑定而不是IO绑定。理论上,只要您不使用任何Java EE功能(并在应用程序取消部署时终止它们),Java EE中的产生线程线程就是安全的。例如:
这些功能通常也会使任务IO绑定而不是CPU绑定。
是的,同样的问题适用于JDK 8并行流。
答案 2 :(得分:1)
您可以创建Singleton ejb,类似于“服务”(即JMX服务)。在此特殊服务的上下文中,您可以控制线程和同步。所以,你可以创建一个singleton ejb,用fork / join逻辑封装作业执行,你的标准ejbs / mdbs可以使用这个服务。
答案 3 :(得分:-2)
在JavaEE中,容器控制线程。想象一下如果每个程序员决定创建自己的线程会发生什么?无论如何,在Java8的并行批量操作中使用线程已被拒绝。 SEE HERE你可以做任何你想要的假设,是的,我写了这篇文章。