无状态会话bean中的multithreading?

EJB 3.0规范不允许无状态会话bean的业务方法创建新线程。 这是为什么? 创建仅执行原始计算并且从不调用应用程序服务器的其他工作线程有什么问题?

比如说,我的会话bean实现了一个允许用户上传图像的服务,而业务方法对这些图像进行了cpu密集型图像处理。 那么即使机器有8个或更多核心,它也只能使用一个cpu核心来完成这项工作? 如果我利用第三方图像处理库,在内部创建工作线程,我也会违反EJB规范,即使该库和这些线程根本与EJB容器无关。 这似乎不对。

如果我忽略EJB规则并仍然创建一些工作线程来进行cpu密集处理会发生什么? 当然这些线程永远不会触及任何app服务器对象,bean线程会在返回之前加入它们。 还能发生什么坏事吗?

EJB 3.0规范不允许无状态会话bean的业务方法创建新线程。 这是为什么?

简短版本:不允许管理来自EJB的线程,因为它会损害资源管理,事务管理,安全性(技术原因),也因为这是EJB模型不想推广的东西(哲学原因)。

EJB规范如下所示:

21.1.2编程限制

  • 企业bean不得尝试管理线程。 企业bean不得尝试启动,停止,挂起或恢复线程,也不得尝试更改线程的优先级或名称。 企业bean不得尝试管理线程组。

这些函数是为EJB容器保留的。 允许企业bean管理线程会降低容器正确管理运行时环境的能力。

也可以看看

  • 为什么不允许创建和管理线程? 在EJB限制常见问题中
  • 为什么不允许bean创建自己的线程?
  • Java EE的并发实用程序
    • 第2.1节“容器管理与非管理线程”

(…)如果我利用第三方图像处理库,在内部创建工作线程,我也会违反EJB规范,即使该库和这些线程根本与EJB容器无关。 这似乎不对。

我能说什么,如果你不喜欢这样,就不要使用EJB。

如果我忽略EJB规则并仍然创建一些工作线程来进行cpu密集处理会发生什么? 当然这些线程永远不会触及任何app服务器对象,bean线程会在返回之前加入它们。 还能发生什么坏事吗?

这些线程是否正在触摸app服务器对象无关紧要。 规则是规则,你不想跟随它们,你是独立的,行为是不确定的。 有些容器可能更宽松并允许它,有些则不会,你的应用程序将无法移植等等。但它仍然是明确禁止的。

如果要以标准方式“生成”线程,请使用WorkManager API或使用JMS。

相关问题

  • EJB如何并行化长时间CPU密集型流程?

一种解决方法:

import java.util.concurrent.Executor; import javax.ejb.Asynchronous; import javax.ejb.Stateless; @Stateless public class TransactionalExecutor implements Executor { @Override @Asynchronous public void execute(Runnable command) { command.run(); } } 

现在您可以使用TransactionalExecutor作为执行程序:

 @Stateless public class SlowService { @Inject Executor command; public void invoke(){ Runnable command = new Runnable() { @Override public void run() { // heavy task } }; command.execute(command); } } 

这是已知的限制,不要在J2EE应用程序中使用线程。 应用程序服务器应该负责程序的并行执行

是的,您可以忽略EJB规则,但可能面临极不可预测的行为

在我简化的理解中,就像经营公司一样。 你是老板(集装箱),而且有一个员工突然只是雇佣了100个人而没有任何通知(豆子)。

但是你仍然可以使用@Asynchronous注释轻松地进行multithreading处理(还有其他方法)。

 @Stateless public class Employee { @Asynchronous public Future work(Project projectThatTakeTooLong) { // work work work return new AsyncResult(null); } } @Stateless public class Boss { @Inject private Employee randomStatelessEmployee; public void giveWork() { Future result1 = randomStatelessEmployee.work(new Project()); Future result2 = randomStatelessEmployee.work(new Project()); Future result3 = randomStatelessEmployee.work(new Project()); result1.get(); result2.get(); result3.get(); } } 

这里还有一个更好的例子: Jboss Java EE容器和ExecutorService