ScheduledThreadPoolExecutor和corePoolSize 0?

时间:2010-02-25 16:36:15

标签: java concurrency multithreading threadpool

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

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

如果没有在ScheduledThreadpoolExecutor周围编写自己的包装,我能否告诉我是否可以达到目标?

提前致谢!

4 个答案:

答案 0 :(得分:14)

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

  • 创建新的ScheduledThreadPoolExecutor
  • 在构造函数中将核心线程设置为您想要的最大线程数
  • 设置执行者的keepAliveTime
  • 最后,允许核心线程超时

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

    这仅适用于Java 6,但

答案 1 :(得分:8)

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

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

答案 2 :(得分:7)

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

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

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

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

答案 3 :(得分:5)

此问题是ScheduledThreadPoolExecutor(Bug ID 7091003)中的已知错误,已在Java 7u4中修复。虽然looking at the patch,但修复是“即使corePoolSize为0,也会启动至少一个线程。”

相关问题