Multithreading in a stateless session bean?

后端 未结 4 2033
梦如初夏
梦如初夏 2020-12-14 23:50

The EJB 3.0 specification does not allow a business method of a stateless session bean to create new threads. Why is that? What is wrong with creating additional worker thre

相关标签:
4条回答
  • 2020-12-15 00:29

    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).

    But you can still easily do multithreading with the @Asynchronous annotation (there are other ways too).

    @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

    0 讨论(0)
  • 2020-12-15 00:41

    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:

    @Stateless
    public class SlowService {
    
        @Inject
        Executor command;
    
        public void invoke(){
            Runnable command = new Runnable() {
                @Override
                public void run() {
                    // heavy task
                }
            };
            command.execute(command);
        }    
    }
    
    0 讨论(0)
  • 2020-12-15 00:45

    This is known restriction not to use threads in J2EE applications. 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.

    0 讨论(0)
  • 2020-12-15 00:48

    The EJB 3.0 specification does not allow a business method of a stateless session bean to create new threads. 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).

    The EJB specification puts it like this:

    21.1.2 Programming Restrictions

    ...

    • The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt to start, stop, suspend, or resume a thread, or to change a thread’s priority or name. The enterprise bean must not attempt to manage thread groups.

    These functions are reserved for the EJB container. Allowing the enterprise bean to manage threads would decrease the container’s ability to properly manage the runtime environment.

    See also

    • Why is thread creation and management disallowed? in the EJB Restrictions FAQ
    • Why are beans not allowed to create their own threads?
    • Concurrency Utilities for Java EE
      • Section 2.1 "Container-Managed vs. Unmanaged Threads"

    (...) 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. This does not seem right.

    What can I say, don't use EJBs if you don't like this.

    What can happen if i ignore the EJB rules and still create some worker threads to do cpu intensive processing? Of course these threads will never touch any app server objects and the bean thread will join them before returning. 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.

    Related Questions

    • How can an EJB parallelize a long, CPU intensive process?
    0 讨论(0)
提交回复
热议问题