多线程实际上是并行处理还是只是一种错觉?

Mee*_*eet 4 java multithreading

假设有 10 个不相交且独立的任务。如果单线程执行需要10分钟,每个任务需要1分钟,那么10个线程,每个任务一个线程会在1分钟内完成执行吗?

由于一次只能运行一条指令,并假设 CPU 仅运行此进程。多线程是否只是线程之间非常快速的上下文切换,给人一种并行处理的错觉,但实际上并不是在处理?

那么,既然CPU要执行的指令数量是一样的,不管是单线程还是多线程,完成的时间不应该是一样的吗?如果是的话,不是说多线程是并行处理的一种手段是错误的吗?

Ste*_*n C 5

Java 多线程通常提供真正的并行性……而不仅仅是并行性的错觉。

假设有 10 个不相交且独立的任务。如果单线程执行需要10分钟,每个任务需要1分钟,那么10个线程,每个任务一个线程会在1分钟内完成执行吗?

可能是,也可能不是。这取决于以下几点:

  1. 任务真的不相交吗?例如,如果它们涉及共享数据结构和同步,它们就不会脱节。

  2. 是否有(至少)10 个物理内核可用于运行 10 个线程?

  3. 它们对于 10 个线程的足够内存带宽是否对我来说不是对 RAM 的读/写瓶颈?

由于一次只能运行一条指令......

实际上,这在技术上是不正确的。即使使用单个内核,由于流水线,CPU 也可以同时执行多条指令。

但是我们可以说传统机器上的给定内核或超线程通常一次只执行一个指令流。

...假设 CPU 只运行这个进程。

我假设您的意思不是 GPU 1,而是只有一个内核且没有超线程的 CPU。

即使对于如今的低端笔记本电脑/台式机,这些假设也不是有效的假设。

多线程是否只是线程之间非常快速的上下文切换,给人一种并行处理的错觉,但实际上并不是在处理?

实际上,如果您在一个内核上运行多个线程,那么线程之间的上下文切换需要很长时间(数百条硬件指令)。而且它们很少发生。

但是,如果您假设只有一个核心/超线程,那么线程无法并行执行是正确的。

那么,既然CPU要执行的指令数量是一样的,不管是单线程还是多线程,完成的时间不应该是一样的吗?如果是的话,不是说多线程是并行处理的一种手段是错误的吗?

如果您假设只有一个核心/超线程可用,那么您的结论是正确的。然而,这种假设在现代计算机上通常是正确的。

例如,我 3 岁的戴尔笔记本电脑的 CPU 有 2 个内核,每个内核有 2 个超线程,理论上可以提供 4 倍的加速(由于硬件并行性!!)。(这还没有考虑使用 GPU 的可能性......)

请注意,典型的服务器级机器每个刀片有 2 或 4 个 CPU,可能更多。一些服务器级 CPU 达到 16 核或更多。因此,单台计算机拥有 64 个内核的情况并不少见。


1 - 普通 Java 不会将 GPU 用于一般计算,所以这有点不合时宜。


Bas*_*khi 1

是的,Java 本质上是多线程的。一个Java程序可以有许多不同的线程,独立且连续地执行。同一页面上的三个 Java 小程序可以一起运行,每个小程序从 CPU 获得相同的时间,而程序员只需付出很少的额外努力。

这使得 Java 对用户输入的响应非常灵敏。它还有助于提高 Java 的稳健性,并提供一种机制,Java 环境可以通过该机制确保恶意小程序不会窃取主机的所有 CPU 周期。

不幸的是,多线程与 Java 的集成如此紧密,使得 Java 很难移植到 Windows 3.1 或 PowerMac 等本身不支持抢占式多线程的体系结构。

多线程是有一定成本的。多线程之于 Java 就像指针算术之于 C,也就是说,它是极其难以发现的错误的来源。尽管如此,在简单的程序中,可以单独保留多线程并且通常没问题