java - 从 Tomcat 中的 servlet 生成线程的推荐方法是什么

标签 java multithreading tomcat servlets spring-mvc

可能会重复!我正在使用 Tomcat 作为我的服务器,并且想知道在 servlet 中产生具有确定性结果的线程的最佳方法是什么。我正在从 servlet 操作运行一些长时间运行的更新,并希望完成请求并在后台进行更新。与其添加像 RabbitMQ 这样的消息中间件,我认为我可以生成一个可以在后台运行并在自己的时间完成的线程。我在其他 SO 线程中读到,服务器终止了服务器产生的线程,以便它能够很好地管理资源。

在使用 Tomcat 时,是否有推荐的生成线程、后台作业的方法。我还将 Spring MVC 用于应用程序。

最佳答案

在 Tomcat 或 Jetty 等准系统 servlet 容器中,您最安全的选择是使用具有最大线程数的应用程序范围的 线程池,以便任务在必要时排队。 ExecutorService 在这方面很有帮助。

在应用程序启动或 servlet 初始化时使用 Executors 创建一个类:

executor = Executors.newFixedThreadPool(10); // Max 10 threads.

然后在servlet的服务期间(你可以忽略你不感兴趣的情况下的结果,或者将它存储在 session 中以供以后访问):

Future<ReturnType> result = executor.submit(new YourTask(yourData));

在哪里 YourTask必须执行RunnableCallable看起来像这样,yourData只是您的数据,例如填充了请求参数值(请记住,您绝对不应该传递 Servlet API 工件,例如 HttpServletRequestHttpServletResponse!):

public class YourTask implements Runnable {

    private YourData yourData;

    public YourTask(YourData yourData) {
        this.yourData = yourData;
    }

    @Override
    public void run() {
        // Do your task here based on your data.
    }
}

最后,在应用程序关闭或 servlet 销毁期间,您需要显式关闭它,否则线程可能会永远运行并阻止服务器正常关闭。

executor.shutdownNow(); // Returns list of undone tasks, for the case that.

如果您实际上使用的是正常的 JEE 服务器,例如 WildFly、Payara、TomEE 等,而 EJB 通常可用,那么您可以简单地输入 @Asynchronous您从 servlet 调用的 EJB 方法上的注释。您可以选择让它返回 Future<T>AsyncResult<T>作为具体值。

@Asynchronous
public Future<ReturnType> submit() {
    // ... Do your job here.

    return new AsyncResult<ReturnType>(result);
}

另见:

关于java - 从 Tomcat 中的 servlet 生成线程的推荐方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3745905/

相关文章:

java - 在 tomcat 服务器上的 Web 应用程序中使用 SVNKit 时 JRE 崩溃

java - 如何将 JSON 转换为 Java 对象,反之亦然

java - 大型项目代码格式化的最佳实践

c++ - 如何正确同步这两个线程?

c - 如何使用 C 套接字在不同线程中接收和发送

java - Apache Tomcat 应用程序中的相对文件路径引用

jsp - Tomcat 6 中的自定义 JSP 编译器?

java - 在 onCreate 方法中初始化 Strings[]

java - hibernate 配置文件

java - 使用spring任务调度处理多个文件时如何保持一致性?