Java Servlet中的ExecutorService

use*_*019 5 java concurrency multithreading servlets java-ee

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

在Java servlet中使用ExecutorService时,能否建议以下哪种设计更好?

1)(为每个请求创建newFixedThreadPool并尽快关闭它)

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();
     }

}
Run Code Online (Sandbox Code Playgroud)

2)(在Servlet Init期间创建newFixedThreadPool并在servlet 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();
     }

}
Run Code Online (Sandbox Code Playgroud)

3)(在Servlet Init期间创建newCachedThreadPool并在servlet destroy上关闭它)

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();
      }

}
Run Code Online (Sandbox Code Playgroud)

小智 1

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

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