代码之家  ›  专栏  ›  技术社区  ›  Martin Carpella

是否计划了线程池执行器和CorePoolSize 0?

  •  15
  • Martin Carpella  · 技术社区  · 16 年前

    我想要一个 ScheduledThreadPoolExecutor 如果没有工作要做,它还会停止最后一个线程;如果有新任务,它还会创建(并使线程保持一段时间的活动状态)。但是一旦没有更多的工作要做,它应该再次丢弃所有线程。

    我Naivly创造了它 new ScheduledThreadPoolExecutor(0) 但结果是,既没有创建线程,也没有执行任何计划任务。

    有人能告诉我,如果我能实现我的目标,而不写我自己的包装纸 ScheduledThreadpoolExecutor ?

    事先谢谢!

    4 回复  |  直到 14 年前
        1
  •  14
  •   sjr    14 年前

    实际上你可以做到,但这并不明显:

    • 创建新的scheduledthreadpoolExecutor
    • 在构造函数中,将核心线程设置为所需的最大线程数。
    • 设置执行者的KeepaliveTime
    • 最后,允许核心线程超时

      m_Executor = new ScheduledThreadPoolExecutor ( 16,null );
      m_Executor.setKeepAliveTime ( 5, TimeUnit.SECONDS );
      m_Executor.allowCoreThreadTimeOut ( true );
      

      这只适用于Java 6。

        2
  •  8
  •   Isaiah van der Elst    14 年前

    阅读threadpoolexecutor javadocs可能会建议亚历克斯V的解决方案是好的。但是,这样做将导致不必要的创建和销毁线程,而不像兑现的线程池。scheduledThreadPool不适用于可变线程数。在查看了源代码之后,我确信您将在每次提交任务时都生成一个新线程。即使你只提交延迟的任务,Joe的解决方案也应该有效。

    我会监视您的线程,以确保您不会在当前的实现中浪费资源。

        3
  •  7
  •   Joe Carnahan    16 年前

    我怀疑里面什么都没有 java.util.concurrent 将为您执行此操作,因为如果您需要计划的执行服务,那么通常会有重复的任务要执行。如果您有一个定期任务,那么它 通常 只保留相同的线程,并将其用于任务的下一个循环,而不是拆掉线程并在下一个循环中构建一个新线程,这样做更有意义。

    当然,一个计划的执行器可以用于在非重复性任务之间插入延迟,或者它可以用于资源如此稀缺且重复性如此罕见的情况,以至于在新的工作到来之前删除所有线程是有意义的。所以,我可以看到你的建议绝对有意义的案例。

    为了实现这一点,我将考虑尝试从 Executors.newCachedThreadPool 以及单线程的计划执行器服务(即 new ScheduledThreadPoolExecutor(1) )任务可以通过计划的执行器服务进行计划,但是计划的任务将以这样的方式进行包装,即单线程执行器不会让单线程计划的执行器执行任务,而是将它们移交给缓存的线程池以供实际执行。

    当绝对没有工作要做时,这种折衷会给您最多运行一个线程,当有很多工作要做时,它会给您所需的线程(当然,在系统的限制范围内)。

        4
  •  5
  •   Esko Luontola    14 年前

    此问题是scheduledThreadPoolExecutor中的已知错误( Bug ID 7091003 并且已经被固定在Java 7U4中。虽然 looking at the patch 修复方法是“即使corepoolsize为0,也至少启动一个线程。”