【问题标题】:Multithreading inside Tomcat - Create a Thread PoolTomcat 内部的多线程 - 创建线程池
【发布时间】:2016-05-21 10:20:54
【问题描述】:

我有一个 servlet,它用于需要几分钟才能完成的漫长过程。收到对此 servlet 的请求后,会在线程内执行长进程,以便由于超时问题立即将响应发送回客户端:

public class TestServlet extends HttpServlet {

    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
        //Thread safe code
        Thread thread = new Thread() {
            public void run() {
                try {
                    Thread.sleep(10000); //simulate long processing
                } catch(InterruptedException v) {
                }
            }  
        };

        thread.start();
    }

}

这意味着每次我收到请求时,都会创建一个新线程。为了不遇到攻击的风险,我需要控制允许多少线程。这意味着在上下文中有一个池,并在所有线程都忙时实现快速失败。

我在看Executor 界面。我的问题是,我怎样才能实现这个线程池执行器,以便从收到的所有请求中访问并充当所有线程的队列?我是否应该将执行程序声明为 servlet 中的本地非线程安全变量,以便该 servlet 的所有实例都可以访问,如下所示?

public class TestServlet extends HttpServlet {

    //non-thread safe variables
    //declare executor here

    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
        //instantiate executor in case it is null

        Thread thread = new Thread() {
            public void run() {
                try {
                    Thread.sleep(10000); //simulate long processing
                } catch(InterruptedException v) {
                }
            }  
        };

        //add thread to the executor
    }
}

或者是否可以在上下文级别声明这个执行器?

我也在查看Tomcat Executor,我相信Tomcat 本身使用它来管理它的线程。是否可以将这些线程也添加到此执行程序中?

【问题讨论】:

  • 只是想知道您不能只获取活动线程数 (java.lang.Thread.activeCount()),如果它超过了您不想为该用户创建线程的线程数吗?
  • 由于什么超时问题?客户端超时应设置为相对于预期的服务时间。如果您将进程发送到另一个线程并立即响应客户端,则您无法向客户端发出进程失败的信号,并且客户端无法确定该进程花费了太长时间并超时。如果 10 秒的睡眠准确地模拟了您的过程,那么您一开始就不会也不应该遇到超时问题。
  • 嗨@EJP,不,十秒钟的睡眠不会模拟这个过程。正如我在上面的描述中所说,该过程需要几分钟才能完成。请注意,我对客户端应用程序没有任何控制权,它会在大约 45 秒后超时,而该过程(文档生成)需要几分钟才能完成。这就是为什么我不得不选择这个解决方案

标签: java multithreading tomcat servlets


【解决方案1】:

通常在应用服务器中进行显式线程管理是个坏主意。您可以将 servlet 设置为在新线程本身中运行,从而避免将事情转移到 servlet 内的另一个线程。我还没有查看 Tomcat 是否允许您配置允许的 servlet 的最大同时实例数,因此这可能仍然是一个问题。

如果您明确使用“Thread.sleep()”,请不要像那样放弃“InterruptedException”。这是错误的做法。查找正确的内容(处理并重新中断)。

【讨论】:

  • 是的,我知道例外情况。以上只是一个示例代码片段。
猜你喜欢
  • 2015-04-30
  • 2023-02-02
  • 2017-04-04
  • 2020-01-06
  • 2017-06-26
  • 2019-09-21
  • 1970-01-01
  • 1970-01-01
  • 2016-04-12
相关资源
最近更新 更多