具有单个线程池的设计是否比多个线程池更好

在Java中拥有多个线程池的优点和缺点是什么?我见过代码中有多个线程池用于不同的“类型”任务,我不确定它是更好的设计还是开发人员懒惰。一个例子是将 ScheduledThreadPoolExecutor 用于定期执行或具有超时的任务,而对其他所有任务使用另一个 ThreadPoolExecutor。


答案 1

拥有单独的专用线程池的目的是使活动不会因为其他活动占用了所有线程而挨饿。如果某些服务有自己的线程池,那么它可以确保拥有一定数量的线程,并且它对其他服务的需求不那么敏感。

操作系统线程是一种有限的资源。如果您的应用程序将线程用于不同的目的,则其中一些应用程序可能会变得繁忙,并使许多线程为它们工作,或者某些服务可能存在错误,即在某些情况下线程不会返回到池中。如果这种情况可能发生在一个线程上,则相同的情况可能适用于所有线程,并且可以通过这种方式排出整个线程池。(在 Release It! 一书的早期有一个例子描述了一个数据库被切换的情况,而写得不好的 JDBC 代码导致了这样的泄漏。

使用多个专用线程池,如果服务需要太多线程,那么它必须等待线程可用,从而在系统中引入背压,使其逐渐降低,并且由于其他部分有自己的线程池,因此它们有机会赶上它们的部分。因此,我们的想法是,随着负载的变化,系统应该具有更稳定的特性。在您描述为计划任务使用单独的线程池的情况下,无论系统的其余部分有多忙,都可以确保这些任务都能运行。

多个线程池需要调整,以确保每个池都有足够的线程,而不是太多。使用单个线程池,这可能会减少空闲线程的数量,并可能更好地利用更多线程,但是您无法预测知道某些重要任务将及时获得完成所需的线程。


答案 2

拥有单个线程池不是一个好的设计,因为在1线程池的情况下,如果应用程序的一部分变慢,线程将集中在那里。如果未实现正确的超时,线程将保留并消耗资源。许多这样的线程和连接可能会导致我们的系统中断,因为没有线程可以留给新的请求。

另一方面,具有多个线程池可确保问题得到控制,并且不会成为系统范围的故障。我们可以有不同的线程池来接受连接,运行批处理作业,与远程API的数据库通信。它确实在一定程度上降低了效率,但使我们的系统变得健壮和容错