Java线程和核心数

时间:2016-01-09 04:35:14

标签: java multithreading concurrency cpu-cores

我刚才有一个关于处理器和线程如何工作的快速问题。根据我目前的理解,核心一次只能执行1个进程。但是我们能够生成一个线程池(比方说30),其数量大于我们拥有的核心数量(假设为4)并让它们同时运行。如果我们只有4个核心,这怎么可能?我也可以在我的本地计算机上运行我的30线程程序,并继续在我的计算机上执行其他活动,如观看电影或浏览互联网。

我已经读过某个地方发生了线程调度,并且这种错误表明这30个线程由4个内核同时运行。这是真的,如果是这样,有人可以解释这是如何工作的,并建议一些好的阅读吗?

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:31)

进程与线程

在旧的日子里,每个进程只有一个执行的线程,因此进程被直接安排到核心上(在过去,几乎只有一个核心可以安排到其上)。但是,在支持线程的操作系统(几乎都是现代操作系统)中,它是线程,而不是已调度的进程。因此,对于本讨论的其余部分,我们将专门讨论线程,您应该了解每个正在运行的进程都有一个或多个执行线程。

并行与并发

当两个线程以并行运行时,它们同时运行 。例如,如果我们有两个线程A和B,那么它们的并行执行将如下所示:

CPU 1:A ------------------------->

CPU 2:B ------------------------->

当两个线程同时运行 时,它们的执行重叠。重叠可以通过以下两种方式之一发生:线程正在同时执行(即并行,如上所述),或者它们的执行在处理器上交错,如下所示:

CPU 1:A -----------> B ----------> A -----------> B ---------->

所以,出于我们的目的,并行性可以被认为是并发的一个特例*

调度

  

但是我们能够生成一个线程池(比方说30),其数量大于我们拥有的核心数量(假设为4)并让它们同时运行。如果我们只有4个核心,这怎么可能?

在这种情况下,它们可以并发运行,因为CPU调度程序正在为这30个线程中的每一个分配一些CPU时间。有些线程并行运行(如果你有4个内核,那么4个线程将同时并行运行),但所有30个线程将同时运行。你可以去玩游戏或浏览网页的原因是这些新线程被添加到线程池/队列中,并且还分配了CPU时间。

逻辑与物理核心

  

根据我目前的理解,核心一次只能执行1个过程

这不是相当是真的。由于非常聪明的硬件设计和流水线操作要花费太长时间才能进入(加上我不理解),一个物理内核可能实际执行两个完全不同的执行线程同时

。如果你需要,可以稍微咀嚼这句话 - 它仍然让我大吃一惊。

这个惊人的壮举被称为同时多线程(或普遍的超线程,虽然这是这种技术的特定实例的专有名称)。因此,我们有物理内核,它们是实际的硬件CPU内核,逻辑内核,这是操作系统告诉软件可以使用的内核数量。逻辑核心本质上是一种抽象。在典型的现代Intel CPU中,每个物理内核充当两个逻辑核心。

  

有人可以解释这是如何运作的,并建议一些好的阅读吗?

如果您真的想了解进程,线程和日程安排如何协同工作,我建议操作系统概念

  • 术语 parallel 并发的确切含义引起了激烈争论,甚至是here in our very own stack overflow。这些术语的含义在很大程度上取决于应用领域。

答案 1 :(得分:4)

简而言之,您对核心的理解是正确的。核心可以一次执行1个线程(也称为进程)。

但是,您的程序不会真正一次运行30个主题。在这30个线程中,一次只运行4个,另外26个正在等待。 CPU将调度线程并为每个线程分配一段时间在核心上运行。因此CPU将使所有线程轮流运行。

一个常见的误解:

  

拥有更多线程将使我的程序运行得更快。

FALSE:拥有更多线程将 NOT 始终使您的程序运行得更快。它只是意味着CPU必须进行更多的切换,事实上,由于切换所有不同进程所产生的开销,拥有太多线程会使程序运行更慢

答案 2 :(得分:3)

Java不执行线程调度,它将此保留在操作系统上以执行线程调度。

对于计算密集型任务,建议使线程池大小等于可用核心数。但对于 I / O绑定任务,我们应该有更多的线程。如果两种类型的任务都可用且需要CPU时间片,还有许多其他变体。

  

核心一次只能执行1个进程

是的,但他们可以多任务并创建一个幻觉,他们一次只能处理多个流程

  

如果我们只有4个核心,这怎么可能?我也能   在我的本地计算机上运行我的30线程程序,并继续   在我的电脑上执行其他活动

由于多任务并发),这是可能的。假设您启动了30个线程,OS也运行了50个线程,所有80个线程将通过逐个获取CPU时间片(每个核心一次一个线程)共享4个CPU核心。这意味着平均每个核心将同时运行80/4 = 20个线程。您会感觉所有线程/进程同时运行。

  

有人可以解释这是如何工作的

所有这些都发生在操作系统级别。如果您是程序员,那么您不必担心这一点。但如果你是操作系统的学生,那么选择任何操作系统书籍和详细了解操作系统级别的多线程,或者深入了解一些优秀的研究论文。有一件事你应该知道每个操作系统以不同的方式处理这些事情(但通常概念是相同的)

有一些语言,如 Erlang ,它们使用绿色线程(或进程),因此他们可以自己映射和调度线程,从而消除操作系统。因此,如果您有兴趣,也可以对绿色线程进行一些研究。

注意:您还可以研究 actor ,这是线程上的另一个抽象。 Erlang,Scala等语言使用actor来完成任务。一个线程可以拥有数百个演员;每个actor都可以执行不同的任务(类似于java中的线程)。

这是一个非常广泛而活跃的研究课题,还有很多东西需要学习。