Java 无状态会话bean中的多线程?
EJB3.0规范不允许无状态会话bean的业务方法创建新线程。为什么呢?创建只进行原始计算而从不调用应用服务器的额外工作线程有什么错 比如说,我的会话bean实现了一个允许用户上传图像的服务,业务方法对这些图像进行cpu密集型的图像处理。那么,即使机器有8个或更多内核,它也只能使用一个cpu内核来完成这项工作?如果我使用第三方图像处理库,该库在内部创建工作线程,我也会违反EJB规范,即使该库和这些线程与EJB容器没有任何关系。这似乎不对 如果我忽略EJB规则,仍然创建一些工作线程来进行cpu密集型处理,会发生什么?当然,这些线程永远不会接触任何appserver对象,bean线程将在返回之前加入它们。还会有不好的事情发生吗 EJB3.0规范不允许无状态会话bean的业务方法创建新线程。为什么呢 简短版本:不允许从EJB管理线程,因为这会损害资源管理、事务管理和安全性(技术原因),也因为这是EJB模型不希望推广的东西(哲学原因) EJB规范是这样描述的: 21.1.2编程限制Java 无状态会话bean中的多线程?,java,multithreading,jakarta-ee,ejb-3.0,ejb,Java,Multithreading,Jakarta Ee,Ejb 3.0,Ejb,EJB3.0规范不允许无状态会话bean的业务方法创建新线程。为什么呢?创建只进行原始计算而从不调用应用服务器的额外工作线程有什么错 比如说,我的会话bean实现了一个允许用户上传图像的服务,业务方法对这些图像进行cpu密集型的图像处理。那么,即使机器有8个或更多内核,它也只能使用一个cpu内核来完成这项工作?如果我使用第三方图像处理库,该库在内部创建工作线程,我也会违反EJB规范,即使该库和这些线程与EJB容器没有任何关系。这似乎不对 如果我忽略EJB规则,仍然创建一些工作线程来进行cpu密集
- 企业bean不能试图管理线程。企业bean不能尝试启动、停止、挂起或恢复线程,也不能更改线程的优先级或名称。企业bean不能试图管理线程组
- 在
-
- 第2.1节“容器托管线程与非托管线程”
是的,您可以忽略EJB规则,但可以面对极其不可预测的行为。在我的简单理解中,这就像经营一家公司。你是老板(容器),有一个员工突然突然在没有任何通知的情况下雇佣了100人(豆子) 但您仍然可以轻松地使用@Asynchronous注释进行多线程处理(还有其他方法)
@无状态
公营雇员{
@异步的
公共未来工作(需要很长时间的项目){
//工作
返回新的异步结果(空);
}
}
@无国籍
公务舱老板{
@注入
私人雇员;
公共工程(){
Future result1=randomstationemployee.work(新项目());
Future result2=randomstationemployee.work(新项目());
Future result3=randomstationemployee.work(新项目());
结果1.get();
结果2.get();
结果3.get();
}
}
这里还有一个更好的例子:
一种解决方法:
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);
}
}
@Stateless
public class SlowService {
@Inject
Executor command;
public void invoke(){
Runnable command = new Runnable() {
@Override
public void run() {
// heavy task
}
};
command.execute(command);
}
}