一段时间以来,我一直对 ThreadPoolExecutor
的默认行为感到沮丧,因为它支持我们许多人使用的 ExecutorService
线程池。引用 Javadocs 的一句话:
If there are more than corePoolSize but less than maximumPoolSize threads running, a new thread will be created 只有在队列满员的情况下.
这意味着如果使用以下代码定义一个线程池,它将启动第二个线程,因为 LinkedBlockingQueue
是无界的。
ExecutorService threadPool =
new ThreadPoolExecutor(1 /*core*/, 50 /*max*/, 60 /*timeout*/,
TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(/* unlimited queue*/));
只有当您有一个 有界队列并且该队列是 满了时,才会启动核心数以上的任何线程。我怀疑许多初级 Java 多线程程序员不知道 ThreadPoolExecutor
的这种行为。
Now I have specific use case where this is not-optimal. I'm looking for ways, without writing my own TPE class, to work around it.
My requirements are for a web service that is making call-backs to a possibly unreliable 3rd party.
newFixedThreadPool(...)
中有大量的线程,而这些线程大多数都处于休眠状态。newCachedThreadPool()
使我的网络服务器的其他部分不堪重负。在需要绑定队列并启动完整的 之前更多线程的 ThreadPoolExecutor
中,如何解决这个限制?如何让它启动更多线程 之前排队任务?
编辑:
@ Flavio 很好地阐述了如何使用 ThreadPoolExecutor.allowCoreThreadTimeOut(true)
实现核心线程的超时和退出。我考虑过这一点,但我仍然想要核心线程特性。如果可能的话,我不希望池中的线程数量低于核心大小。