首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中的ExecutorService

Java中的ExecutorService
EN

Stack Overflow用户
提问于 2012-08-02 21:08:20
回答 2查看 6.1K关注 0票数 6

我需要在java中并发地执行一些任务(主要是调用具有请求参数和读取数据的多个外部URL),并在几秒钟内向用户发送响应。我需要在FutureTasks方法中的每个用户请求中创建四个doGet。每个任务运行约5-10秒,对用户的总响应时间约为15秒。

请您建议在Java中使用ExecutorService时,下列哪一种设计更好?

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

代码语言:javascript
复制
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();
     }

}

( 2) (在Servlet期间创建newFixedThreadPool并在servlet销毁时关闭)

代码语言:javascript
复制
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();
     }

}

3) (在Servlet期间创建newCachedThreadPool并在servlet销毁时关闭)

代码语言:javascript
复制
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();
      }

}
EN

回答 2

Stack Overflow用户

发布于 2012-08-02 21:56:24

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

至于在2和3之间的选择,请在下面的帖子中检查接受的答案。答案解释了不同之处,然后你可以决定哪一个更适合你的需要:newcachedthreadpool-v-s-newfixedthreadpool

票数 1
EN

Stack Overflow用户

发布于 2012-08-02 22:47:22

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

如果您有某种方法来记住每个URL获取任务都与哪个HTTP请求相关,我会选择一个CachedThreadPool。它按需增长和收缩的能力将产生奇迹,因为URL获取任务是完全独立和网络绑定的(相对于CPU或内存绑定)。

另外,我会将ThreadPool包装在一个CompletionService中,无论它的提交顺序如何,只要完成了一项任务,它都可以通知您。先完成,先通知。这将确保,如果更快的工作已经完成,你不会阻止一个低血缘作业。

CompletionService很容易使用:将其封装在现有的ThreadPool (例如newCachedThreadPool)周围,向其提交()作业,然后返回()结果。请注意,note ()方法是阻塞的。

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CompletionService.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11785801

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档