ScheduledThreadPoolExecutor和corePoolSize 0?

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

我天真地将它创建为new ScheduledThreadPoolExecutor(0)但结果是,没有创建任何线程,也没有执行任何计划任务。

任何人都可以告诉我,如果我没有在ScheduledThreadpoolExecutor周围编写自己的包装器就可以实现我的目标吗?

提前致谢!

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

  • 创建一个新的ScheduledThreadPoolExecutor
  • 在构造函数中,将核心线程设置为所需的最大线程数
  • 设置执行程序的keepAliveTime
  • 最后,允许核心线程超时

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

    这仅适用于Java 6

阅读ThreadPoolExecutor javadocs可能表明Alex V的解决方案没问题。 但是,这样做会导致不必要地创建和销毁线程,而不像一个兑现的线程池。 ScheduledThreadPool不适用于可变数量的线程。 查看了源代码后,我确信您几乎每次提交任务时都会产生一个新线程。 即使您只提交延迟任务,Joe的解决方案也应该有效。

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

我怀疑java.util.concurrent提供的任何内容都不会为您执行此操作,因为如果您需要预定的执行服务,那么您通常需要执行重复任务。 如果你有一个重复的任务,那么通常更有意义的是保持相同的线程并将其用于下一次重复任务,而不是拆除你的线程并在下一次重复时建立一个新线程。

当然,可以使用预定的执行程序来插入非重复任务之间的延迟,或者可以在资源非常稀缺的情况下使用它,并且很少发生重复,以至于在新工作到来之前拆除所有线程是有意义的。 所以,我可以看到你的提案肯定有意义的案例。

为了实现这一点,我会考虑尝试将Executors.newCachedThreadPool的缓存线程池与单线程调度执行程序服务(即new ScheduledThreadPoolExecutor(1) )一起包装起来。 可以通过计划的执行程序服务来安排任务,但是计划的任务将以这样的方式包装,即单线程执行程序不会让您的单线程调度执行程序执行它们,而是将它们交给缓存的线程池以实现执行。

当完全没有工作要做时,这种妥协会让你最多运行一个线程,并且当你需要做很多工作时,它会给你你所需要的线程数量(在你的系统范围内) 。

此问题是ScheduledThreadPoolExecutor中的已知错误( 错误ID 7091003 ),已在Java 7u4中得到修复。 虽然看了补丁 ,但修复是“即使corePoolSize为0,也至少启动一个线程”。