我的应用程序中有3个fixedThreadPools,每个大小为20个。
我在池中提交任务但是很少有人在每个pool1,pool2,pool 3中说5个任务,所以每个池中有15个线程处于空闲状态。我想知道这些空闲线程(总共45个)是否会进入上下文切换并降低性能,即使没有提交任务?
答案 0 :(得分:2)
如果池化的线程没有任务,则它们处于状态WAITING,这意味着它们除了等待信号发生之外没有任何关系(在这种情况下,等待提交任务)。它们没有安排任何CPU时间,因为它们无关。调度程序足够聪明,可以知道这一点,所以在这一点上,它被排除在与其他更活跃的线程竞争资源之外。
如果一个线程处于RUNNABLE
状态,那么它可能有实际的事情,并且给了CPU时间。
因此,池中的多余线程不会与实时线程竞争,但它们确实需要少量本机资源(在谈论60个线程时,这并不足以真正重要)。
答案 1 :(得分:2)
我的应用程序中有3个fixedThreadPools,每个大小为20个。
您的意思是,您正在创建3个ExecutorService
线程池大小20
的实例。这意味着池中的总60
个线程?
......每个池中的15个线程处于空闲状态。我想知道这些 空闲线程(共45个)将进入上下文切换..
我认为,您假设同时运行所有60个线程,因为您已经提到了每个池中的5个线程(即15个线程)正在执行。但剩下的45个线程(每个池中有15个线程)处于空闲状态。但是,在他们让任务分配和可用核心数来执行它们之前,这是不正确的。
请注意,线程的执行取决于可用内核(CPU)的数量。无论你创建了多少线程,如果CPU无法执行每个线程,它们将处于Runnable
状态以获得转弯。
JVM决定应该运行哪个线程以及如何运行,主要使用抢占式或时间切片调度来调度线程。在那个时候,如果其他线程获得一个新任务(或者有一些任务要执行),那么他们将在Runnable
状态下轮到他们。
答案 2 :(得分:-1)
与其他执行者不同,ForkJoinPool支持work stealing。 是的,当没有执行任务时,线程会等待,但在此之前,它们会尝试从池的队列中窃取工作,这会消耗更多的CPU,然后是其他执行器(FixedThreadPool,CachedThreadPool)。唤醒线程也需要时间。
ForkJoinPool在有大量工作时表现最佳。如果你没有这个,你最好使用FixedThreadPool。此外,您应该了解通常ForkJoinPool,FixedThreadPool用于CPU密集型任务。否则,如果您有IO密集型任务,最好使用CachedThreadPool。您可以创建一个FixedThreadPool,但应该知道任务可能会相互阻塞。
此外,没有理由创建三个具有60个线程的ForkJoinPool池,除非你有至少32个CPU(但它非常依赖)。由于您无法使用池,因此可能不是您的示例。但请记住,如果你运行大量CPU密集型任务的线程数比CPU大,那么是的,由于资源共享,包括上下文切换,你的性能可能会更差。