Jboss Java EE 容器和 ExecutorService

2022-09-01 12:36:02

我有一个独立的java应用程序,它使用ExperidorService并行处理许多作业

 ExecutorService es = Executors.newFixedThreadPool(10);

我现在想在EJB Bean中重用相同的解决方案,但不确定如何正确初始化ThreadPool,因为我通常会离开Java EE容器来控制所有线程资源。我可以只使用相同的代码,还是有另一种正确的方法来获取 Jboss 托管线程池?


答案 1

在 EJB 中执行此操作的正确方法是使用 ManagedExecutorService,它是 Concurrency Utils API (Java EE7) 的一部分。您不应该在企业代码中使用任何属于 java.util.concurrent 一部分的 ExecutorService。

通过使用 ManagedExecutorService,您的新线程将由容器创建和管理。

以下示例取自我的网站。

若要使用 ManagedExecutorService 创建新线程,请首先创建一个实现 Callable 的任务对象。在 call() 方法中,我们将定义要在单独的线程中执行的工作。

public class ReportTask implements Callable<Report> {

    Logger logger = Logger.getLogger(getClass().getSimpleName());

    public Report call() {
        try {
            Thread.sleep(3000);
        catch (InterruptedException e) {
            logger.log(Level.SEVERE, "Thread interrupted", e);
        }
        return new Report();
    }
}

然后,我们需要通过将任务传递到 ManagedExecutorService 的 submit() 方法来调用该任务。

@Stateless
public class ReportBean {

    @Resource
    private ManagedExecutorService executorService;

    public void runReports() {
        ReportTask reportTask = new ReportTask();
        Future<Report> future = executorService.submit(reportTask);
    }
}

答案 2

强制性警告:不鼓励在 Java EE 应用程序服务器(甚至是 Tomcat)中创建自己的线程,因为它可能是一个巨大的性能问题,并且在大多数情况下会阻止容器功能(如 JNDI)正常工作。新线程将不知道它们属于哪个应用程序,线程上下文类加载器将不会被设置以及许多其他隐藏问题。

幸运的是,有一种方法可以让Java EE服务器通过Java EE 6和这种聪明的设计模式来管理线程池。可移植到任何 Java EE 6 认证的服务器。@Asynchronous

在应用程序中创建此 EJB。

package org.superbiz;

import javax.ejb.Asynchronous;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;

@Stateless(name="Executor")
public class ExecutorBean implements Executor {

    @Asynchronous
    @Override
    public void execute(Runnable command) {
        command.run();
    }
}

然后,您可以通过普通依赖关系注入在应用程序中的其他位置引用此 Bean(如果引用组件是 Servlet、Listener、Filter、其他 EJB、JSF 托管 Bean)。

@EJB
private Executor executor;

然后像往常一样使用。Executor

如果该组件不是另一个 Java EE 组件,则可以通过以下方式查找 Bean:

InitialContext initialContext = new InitialContext();
Executor executor = (Executor) initialContext.lookup("java:module/Executor");

推荐