javaservlet中的ExecutorService

javaservlet中的ExecutorService,java,multithreading,jakarta-ee,servlets,concurrency,Java,Multithreading,Jakarta Ee,Servlets,Concurrency,我需要在JavaServlet中同时执行一些任务(主要是调用多个带有请求参数的外部URL并读取数据),并在几秒钟内向用户发送响应。我正在尝试使用ExecutorService来实现同样的任务。我需要在doGet方法中的每个用户请求中创建四个FutureTasks。每个任务运行约5-10秒,对用户的总响应时间约为15秒 在Javaservlet中使用ExecutorService时,您能建议以下哪种设计更好 1)(根据请求创建新的FixedThreadPool并尽快关闭) 2)(在Servlet初

我需要在JavaServlet中同时执行一些任务(主要是调用多个带有请求参数的外部URL并读取数据),并在几秒钟内向用户发送响应。我正在尝试使用ExecutorService来实现同样的任务。我需要在doGet方法中的每个用户请求中创建四个FutureTasks。每个任务运行约5-10秒,对用户的总响应时间约为15秒

在Javaservlet中使用ExecutorService时,您能建议以下哪种设计更好

1)(根据请求创建新的FixedThreadPool并尽快关闭)

2)(在Servlet初始化期间创建newFixedThreadPool,并在Servlet销毁时将其关闭)

3)(在Servlet初始化期间创建newCachedThreadPool,并在Servlet销毁时将其关闭)


第一种不应该是一种选择。线程池(可能还有任何池)的想法是最小化构建池成员(在本例中为工作线程)所需的开销和内存。因此,一般来说,池应该在应用程序启动时初始化,在应用程序关闭时销毁


至于2和3之间的选择,请在下面的帖子中检查接受的答案。答案解释了差异,然后您可以决定哪一个更适合您的需要:

为每个请求创建和销毁线程池是个坏主意:太贵了

如果您有办法记住每个URL获取任务与哪个HTTP请求相关,我会选择CachedThreadPool。它按需增长和收缩的能力将创造奇迹,因为URL获取任务完全独立且受网络限制(与CPU或内存限制相反)

此外,我将线程池包装在CompletionService中,它可以在作业完成时通知您,而不管其提交顺序如何。首先完成,首先通知。这将确保如果已经完成了更快的工作,您不会阻碍慢行工作

CompletionService易于使用:将其包装在现有线程池(例如newCachedThreadPool)周围,向其提交()作业,然后将()结果取回。请注意take()方法是阻塞的


容器创建并加载servlet的单个实例。所有请求都由同一实例处理。所以,
ExecutorService myThreadPool=null
不安全。因此,可以建议如何全局声明ExecutorService吗?感谢您的回答。根据您建议的链接,newcachedthreadpool似乎很合适,因为我的任务与http请求绑定并在几秒钟内完成。感谢您的回答。请您详细说明“如果您有办法记住每个URL获取任务与哪个HTTP请求相关”,好吗。如果使用cachedthreadpool,任务和请求之间是否有可能不匹配?尽管每个请求的线程池都是相同的,但每个请求的任务都是新的,完成后我可以使用.get()方法进行检索,对吗?嗯,我改变了主意-完成服务要求您在take()方法上有一个线程块,然后将生成的未来重新修补到原始请求,这会很复杂。最好在标准ExecutorService上使用invokeAll():向其提交作业列表,然后返回结果列表。更简单、更高效。
public class MyTestServlet extends HttpServlet
{

    ExecutorService myThreadPool = null;

    public void init()
    {
          super.init();

    }
    protected void doGet(HttpServletRequest request,HttpServletResponse response)
    {

        myThreadPool = Executors.newFixedThreadPool(4);
        taskOne   = myThreadPool.submit();
        taskTwo   = myThreadPool.submit();        
        taskThree = myThreadPool.submit();
        taskFour  = myThreadPool.submit();

        ...
        ...

        taskOne.get();
        taskTwo.get();
        taskThree.get();
        taskFour.get();

        ...

        myThreadPool.shutdown();


    }

     public void destroy()
     {

         super.destroy();
     }

}
public class MyTestServlet extends HttpServlet
{

    ExecutorService myThreadPool = null;

    public void init()
    {
      super.init();
          //What should be the value of fixed thread pool so that it can handle multiple   user requests without wait???
          myThreadPool = Executors.newFixedThreadPool(20);

    }
    protected void doGet(HttpServletRequest request,HttpServletResponse response)
    {


        taskOne   = myThreadPool.submit();
        taskTwo   = myThreadPool.submit();        
        taskThree = myThreadPool.submit();
        taskFour  = myThreadPool.submit();

        ...
        ...

        taskOne.get();
        taskTwo.get();
        taskThree.get();
        taskFour.get();

        ...



    }

     public void destroy()
     {

          super.destroy();
          myThreadPool.shutdown();
     }

}
public class MyTestServlet extends HttpServlet
{

      ExecutorService myThreadPool = null;

      public void init()
      {
        super.init();
            myThreadPool = Executors.newCachedThreadPool();

      }
      protected void doGet(HttpServletRequest request,HttpServletResponse response)
      {


          taskOne   = myThreadPool.submit();
          taskTwo   = myThreadPool.submit();        
          taskThree = myThreadPool.submit();
          taskFour  = myThreadPool.submit();

          ...
          ...

          taskOne.get();
          taskTwo.get();
          taskThree.get();
          taskFour.get();

          ...




     }

     public void destroy()
     {

            super.destroy();
            myThreadPool.shutdown();
      }

}