【问题标题】:Wouldn't each thread require its own copy of the JVM?不是每个线程都需要自己的 JVM 副本吗?
【发布时间】:2012-03-15 00:39:09
【问题描述】:

我试图弄清楚 JVM 在生成多个线程方面是如何工作的。我认为我的心智模型可能有点偏离,但现在我一直在思考这个想法:既然任何时候都只有一个 JVM 副本在运行,那么每个线程不是都需要自己的 JVM 副本吗?我意识到java应用程序的多个线程被映射到本机操作系统线程,但我不明白没有运行JVM的线程是如何处理字节码的;是不是所有线程都可以访问JVM?谢谢,任何帮助表示赞赏。

【问题讨论】:

标签: java multithreading process jvm


【解决方案1】:

这有点过于简单了,我写的一些内容并不完全正确,但本质是这样的:

既然在任何时候都只有一个 JVM 副本在运行,那么每个线程不是都需要自己的 JVM 副本吗?

不是真的。您可以允许多个线程从一块内存中读取(就像在内存中的同一地址中一样),因此只有一个 JVM。但是,您需要小心,以免线程在同时访问此类共享资源 (JVM) 时造成混乱,就像现实世界中的情况一样(想象两个人试图同时键入两个不同的文档一台电脑)。

让多个线程与某些共享资源(例如 JVM(堆栈、堆、字节码编译器)、控制台、打印机等)一起正常工作的一种策略确实是为每个线程创建副本(每个人一台 PC) .例如,每个线程都有自己的堆栈。

然而,这不是唯一的方法。例如,不可变资源(如内存中的类字节码)可以通过共享内存在多​​个线程之间毫无问题地共享。如果一份备忘录没有改变,两个人都可以同时安全地查看该备忘录。同样,由于类字节码不变,多个线程可以同时从一个副本中读取。

另一种方法是使用锁来解决线程之间的问题(触摸鼠标的人就可以使用 PC)。例如,您可以想象一个 JVM,其中只有一个字节码解释器,它在所有线程之间共享并受一个全局锁保护(这在实践中效率非常低,但您明白了)。

还有一些其他高级机制可以让多个线程使用共享资源。开发 JVM 的人使用了这些技术,这就是为什么您不需要每个线程都有一个 JVM 副本。

【讨论】:

    【解决方案2】:

    但我不明白没有运行 JVM 的线程是如何处理字节码的;是不是所有线程都可以访问JVM?

    http://www.artima.com/insidejvm/ed2/jvmP.html 很好地解释了这一点。它是这样说的:

    "运行中的 Java 应用程序的每个线程都是虚拟机执行引擎的不同实例。 从生命周期的开始到结束,线程要么执行字节码,要么执行本地方法。A线程可以直接执行字节码,通过在硅中本地解释或执行,或间接,通过即时编译和执行生成的本地代码。Java 虚拟机实现可以使用正在运行的应用程序不可见的其他线程,例如线程执行垃圾回收。此类线程不必是实现的执行引擎的“实例”。但是,属于正在运行的应用程序的所有线程都是运行中的执行引擎。”

    总结一下我对此的理解:

    对于每个线程(execpt GC 线程和同类),对应的 ExecutionEngine 实例(在同一个 JVM 中)将字节码转换为机器指令,并且本机 OS 线程执行这些机器指令。当然,我不是在这里谈论绿线。

    【讨论】:

    • 很好,这意味着JVM将同时运行多个执行引擎实例
    • 是的,除了像 GC 线程这样不做任何字节码处理的线程。
    【解决方案3】:

    根据定义,Java 应用程序中的线程共享相同的内存空间,因此在相同的 JVM 中执行。通过这种方式,您可以轻松地在多个线程之间共享对象、执行同步等,所有这些都发生在 JVM 中。

    一种看待它的方式是,进程拥有自己的内存空间,而应用程序中的线程共享相同的内存空间。

    【讨论】:

      猜你喜欢
      • 2017-08-11
      • 1970-01-01
      • 2012-04-18
      • 2017-12-19
      • 2013-08-23
      • 1970-01-01
      • 1970-01-01
      • 2017-04-01
      • 2012-01-27
      相关资源
      最近更新 更多