简体   繁体   English

无状态会话bean中的多线程?

[英]Multithreading in a stateless session bean?

The EJB 3.0 specification does not allow a business method of a stateless session bean to create new threads. EJB 3.0规范不允许无状态会话bean的业务方法创建新线程。 Why is that? 这是为什么? What is wrong with creating additional worker threads that only do raw computations and never call into the app server? 创建仅执行原始计算而从不调用应用服务器的附加工作线程有什么问题?

Say, my session bean implements a service that lets users to upload images, and the business method does cpu-intensive image processing on these images. 说,我的会话bean实现了一项服务,该服务允许用户上传图像,而business方法对这些图像进行CPU密集型图像处理。 Then it can only use one cpu core to do this job, even if the machine has 8 or more cores? 那么,即使机器有8个或更多内核,它也只能使用一个cpu内核来完成这项工作? If i utilize a third party image processing library, that internally creates worker threads, i would also violate the EJB specs, even though that library and these threads have nothing to do with the EJB container at all. 如果我利用第三方图像处理库在内部创建工作线程,那么即使该库与这些线程与EJB容器完全无关,我也会违反EJB规范。 This does not seem right. 这似乎不正确。

What can happen if i ignore the EJB rules and still create some worker threads to do cpu intensive processing? 如果我忽略EJB规则并仍然创建一些工作线程来执行cpu密集处理,会发生什么? Of course these threads will never touch any app server objects and the bean thread will join them before returning. 当然,这些线程永远不会触摸任何应用程序服务器对象,并且Bean线程会在返回之前将它们加入。 Can still something bad happen? 还会发生不好的事情吗?

The EJB 3.0 specification does not allow a business method of a stateless session bean to create new threads. EJB 3.0规范不允许无状态会话bean的业务方法创建新线程。 Why is that? 这是为什么?

Short version: managing threads from EJBs is disallowed because it would harm resource management, transaction management, security (technical reasons) and also because this is something the EJB model doesn't want to promote (philosophical reason). 简短版:禁止从EJB管理线程,因为这会损害资源管理,事务管理,安全性(技术原因),并且因为这是EJB模型不希望推广的(哲学原因)。

The EJB specification puts it like this: EJB规范如下所示:

21.1.2 Programming Restrictions 21.1.2编程限制

... ...

  • The enterprise bean must not attempt to manage threads. 企业bean不得尝试管理线程。 The enterprise bean must not attempt to start, stop, suspend, or resume a thread, or to change a thread's priority or name. 企业bean不得尝试启动,停止,挂起或恢复线程,也不能尝试更改线程的优先级或名称。 The enterprise bean must not attempt to manage thread groups. 企业bean不得尝试管理线程组。

These functions are reserved for the EJB container. 这些功能是为EJB容器保留的。 Allowing the enterprise bean to manage threads would decrease the container's ability to properly manage the runtime environment. 允许企业bean管理线程将降低容器正确管理运行时环境的能力。

See also 也可以看看

(...) If i utilize a third party image processing library, that internally creates worker threads, i would also violate the EJB specs, even though that library and these threads have nothing to do with the EJB container at all. (...)如果我利用第三方图像处理库在内部创建工作线程,那么即使该库与这些线程与EJB容器完全无关,我也会违反EJB规范。 This does not seem right. 这似乎不正确。

What can I say, don't use EJBs if you don't like this. 我能说什么,如果您不喜欢EJB,请不要使用。

What can happen if i ignore the EJB rules and still create some worker threads to do cpu intensive processing? 如果我忽略EJB规则并仍然创建一些工作线程来执行cpu密集处理,会发生什么? Of course these threads will never touch any app server objects and the bean thread will join them before returning. 当然,这些线程永远不会触摸任何应用程序服务器对象,并且Bean线程会在返回之前将它们加入。 Can still something bad happen? 还会发生不好的事情吗?

Whether these threads are touching the app server objects or not doesn't matter. 这些线程是否正在接触应用服务器对象并不重要。 Rules are rules, you don't want to follow them, you're on your own and the behavior is undefined. 规则就是规则,您不想遵循它们,您是一个人,行为是不确定的。 Some container might be more permissive and allow it, some other won't, your application won't be portable, etc. But it's still explicitly forbidden. 某些容器可能更宽松,并且允许它使用,而另一些容器则不允许,您的应用程序不能移植,等等。但是仍然明确禁止使用。

If you want to "spawn" threads in a standard way, use the WorkManager API, or use JMS. 如果要以标准方式“产生”线程,请使用WorkManager API或JMS。

Related Questions 相关问题

In my simplified understanding, it's like running a company. 以我的简化理解,这就像经营一家公司。 You're the boss (the container), and there's an employee which suddenly just hire 100 people out of the blue without any notice (the bean). 您是老板(容器),并且有一个雇员突然间突然雇用了100名员工,而没有任何通知(豆子)。

But you can still easily do multithreading with the @Asynchronous annotation (there are other ways too). 但是您仍然可以使用@Asynchronous批注轻松进行多线程处理(还有其他方法)。

@Stateless
public class Employee {
    @Asynchronous
    public Future<Void> work(Project projectThatTakeTooLong) {
        // work work work
        return new AsyncResult<Void>(null);
    }
}

@Stateless
public class Boss {

    @Inject
    private Employee randomStatelessEmployee;

    public void giveWork() {
        Future<Void> result1 = randomStatelessEmployee.work(new Project());
        Future<Void> result2 = randomStatelessEmployee.work(new Project());
        Future<Void> result3 = randomStatelessEmployee.work(new Project());
        result1.get();
        result2.get();
        result3.get();
    }
}

There's also a better example here: Jboss Java EE container and an ExecutorService 这里还有一个更好的示例: Jboss Java EE容器和ExecutorService

One type of workaround: 一种解决方法:

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();
    }
}

Now you can use TransactionalExecutor as an executor: 现在,您可以将TransactionalExecutor用作执行程序:

@Stateless
public class SlowService {

    @Inject
    Executor command;

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

This is known restriction not to use threads in J2EE applications. 这是在J2EE应用程序中不使用线程的限制。 Application server should take care of parallel execution of the program 应用程序服务器应注意程序的并行执行

Yes, you can ignore the EJB rules but can face with extremely unpredictable behaviour . 是的,您可以忽略EJB规则,但是可能会遇到极其不可预测的行为

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM