Java Threads vs OS Threads

看起来我搞砸了Java Threads/OS Threads和解释型语言。

在我开始之前,我确实知道绿色线程是Java线程,其中线程由JVM处理,整个Java进程仅作为单个操作系统线程运行。因此,在多处理器系统上它是无用的。

现在我的问题是。我有两个线程 A 和 B。每个都有10万行独立代码。我在多处理器系统上的Java程序中运行这些线程。每个线程都将获得一个本机操作系统线程来运行,该线程可以在不同的CPU上运行,但是由于Java被解释,这些线程将需要一次又一次地与JVM进行交互,以将字节码转换为机器指令?我说的对吗?如果是的话,比起小程序,Java线程不会有很大的优势吗?

一旦热点编译了这两个执行路径,两者都可以与本机线程一样好?我说的对吗?

[编辑] :另一个问题可能是,假设你有一个Java线程,其代码不是JIT编译的,你创建该线程并启动()它?操作系统线程和 JVM 如何交互来运行该字节码?

谢谢


答案 1

每个线程都将获得一个本机操作系统线程来运行,该线程可以在不同的CPU上运行,但是由于Java被解释,这些线程将需要一次又一次地与JVM进行交互,以将字节码转换为机器指令?我说的对吗?

你正在混合两种不同的东西;由 VM 完成的 JIT 和 VM 提供的线程支持。在内心深处,你所做的一切都转化为某种原生代码。使用线程的字节码指令与访问线程的JIT代码没有什么不同。

如果是的话,比起小程序,Java线程不会有很大的优势吗?

在这里定义小。对于短期进程,是的,线程不会产生太大的差异,因为顺序执行足够快。请注意,这同样取决于要解决的问题。对于 UI 工具包,无论应用程序有多小,都需要某种线程/异步执行来保持 UI 响应。

当您拥有可以并行运行的内容时,线程化也是有意义的。一个典型的例子是在线程上执行繁重的IO,在另一个线程中进行计算。你真的不想仅仅因为你的主线程在IO中被阻塞而阻止你的处理。

一旦热点编译了这两个执行路径,两者都可以与本机线程一样好?我说的对吗?

请看我的第一点。

线程化真的不是银弹,特别是当涉及到“使用线程使代码运行得更快”的常见误解时。一些阅读和经验将是你最好的选择。我可以推荐一本这本很棒的书吗?:-)

@Sanjay:事实上,现在我可以重新构建我的问题。如果我有一个线程的代码尚未被JIT'd,操作系统线程如何执行它?

我再说一遍,线程是一个与JIT完全不同的概念。让我们尝试用简单的术语来看看程序的执行:

java pkg.MyClass -> VM 找到要运行的方法 -> 开始逐行执行方法的字节码 ->将每个字节码指令转换为其本机对应的 ->由 OS 执行的指令 ->由机器执行的指令

当JIT启动时:

java pkg.MyClass -> VM 定位要运行的方法,该方法已经过 JIT'ed ->找到该方法的关联本机代码 -由 OS 执行的>指令 ->由机器执行的指令

如您所见,无论您遵循何种路线,都必须在某个时间点将 VM 指令映射到其本机对应项。该本机代码是存储以供进一步重用,还是在有不同情况时丢弃(优化,还记得吗?)。

因此,为了回答您的问题,每当您编写线程代码时,它都会被转换为本机代码并由操作系统运行。该翻译是动态完成的还是在那个时间点查找的,这是一个完全不同的问题。


答案 2

并且整个 Java 进程仅作为单个操作系统线程运行

事实并非如此。因此,我们经常看到,Java线程实际上是本机操作系统线程,多线程Java应用程序实际上利用多核处理器或多处理器平台。

一个常见的建议是使用线程池,其中线程数与内核数成正比(因子 1-1.5)。这是另一个提示,即JVM不限于单个OS线程/进程。


来自 wkipedia:

在Java 1.1中,绿色线程是JVM使用的唯一线程模型,[4]至少在Solaris上是这样。由于与本机线程相比,绿色线程有一些限制,因此后续的Java版本放弃了它们,转而使用本机线程

现在,早在2010年,Java 7正在开发中,Java 8正在计划中 - 我们真的仍然对历史上的“绿色线程”感兴趣吗?