java - 如何处理 doGet 或 doPost 中潜在的长时间操作?

标签 java multithreading web-applications servlets timeout

在 HTTP POST(由应用程序生成,而不是由用户生成)之后,我想发送一封电子邮件。我的电子邮件发送过程正确,但我不确定 Java Web 应用程序服务器如何工作。

我特别担心超时,我想知道我是否以某种方式阻塞了一个重要的线程。

如果我执行以下操作:

    @Override
    public void doPost(
            final HttpServletRequest req,
            final HttpServletResponse resp
    ) throws IOException, ServletException {
        final PrintWriter pw = resp.getWriter();
        pw.write( ... );
        pw.flush();
        pw.close();
        // Here I'm sending an email, this can potentially
        // block until the email send procedure times out
        // (the timeout is set to 5 seconds)
        sendEmail(...);
    }

如果电子邮件服务器关闭,线程将阻塞,直到我的 sendEmail 超时(我将超时设置为几秒)。

然后我阻塞了哪个线程?我的意思是,显然我意识到我正在阻塞正在处理此 POST 的线程,但这是否是一个问题?该线程下一步应该做什么?

我读到我不应该从 Java webapp 服务器创建新线程,所以我认为我不应该执行以下操作,对吧?

    Thread t = new Thread( new Runnable() {
        public void run() {
            sendEmail();
        }
    });
    t.start();

请注意,我的问题并非特定于电子邮件发送:我想了解每次您计划在 GET 或 POST 之后执行潜在的阻塞/长时间操作时,在 Java Web 应用程序中必须注意什么。

最佳答案

在 servlet 中启动线程是可以的,您只需要非常小心,以确保它在 servlet 取消部署时终止。

最简单的方法是在 servlet 启动时创建一个 java.util.concurrent.ExecutorService 并在 servlet 销毁时将其关闭。然后,您可以将电子邮件作业提交到执行器服务并从 doPost 返回。请注意,如果 servlet 在作业排队后被销毁,则某些电子邮件可能无法发送。

在代码中:

class EmailServlet extends HttpServlet {
    private ExecutorService emailSender;

    public void init() {
        emailSender = Executors.newFixedThreadPool(1);
    }

    public void destroy() {
        emailSender.shutdownNow();
    }

    public void doPost(...) {
        ...
        emailSender.execute(new Runnable() {public void run() {sendEmail();}});
    }
}

关于java - 如何处理 doGet 或 doPost 中潜在的长时间操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4504773/

相关文章:

java - j2me : how to show My Location in google map?

c# - 取消订阅套接字流后取消特定的子线程或任务

c++ - 如何在生产者-消费者场景中使用 Boost 条件变量?

web-applications - iPhone 网络应用程序图标上主屏幕上有未读点

java - 如何提高使用传统数据库(例如只能运行 SQL 而不能运行存储过程的 HP NonStop Tandem)的任何应用程序的性能?

java - java liferay项目中的内存泄漏

java - 电子邮件不是使用 simpleMailMessage 发送的

java - onCreateDialog 和动态对话框 (Android)

php - 如何在 PHP 中正确分离和删除 2 个进程之间的共享内存?

python - 使用各种区域设置对 Python 中的字符串集合进行排序