我正在试图弄清楚JVM如何产生多个线程。我认为我的心理模型可能有点偏差,但是现在我仍然坚持这个想法:因为在任何时候只有一个JVM副本运行,每个线程都不需要自己的JVM副本吗?我意识到java应用程序的多个线程被映射到本机os线程,但我不知道没有运行JVM的线程如何处理字节码;是不是所有线程都可以访问JVM?谢谢,任何帮助表示赞赏。
答案 0 :(得分:3)
这有点过于简单,我写的一些内容并不完全正确,但其实质是:
由于任何时候只运行一个JVM副本,每个线程不会需要自己的JVM副本吗?
不是真的。您可以允许多个线程从一块内存中读取(如在内存中的相同地址中),因此只有一个JVM。但是,您需要小心,以便线程在同时访问此类共享资源(JVM)时不会造成混乱,就像现实世界中的情况一样(想象两个人同时尝试键入两个不同的文档)用一台电脑)。
让多个线程与一些共享资源(例如JVM(堆栈,堆,字节码编译器),控制台,打印机等)一起正常运行的策略确实具有每个线程的副本(每个人一台PC) 。例如,每个线程都有自己的堆栈。
然而,这不是唯一的方法。例如,不可变资源(如内存中的类字节代码)可以通过共享内存在多个线程之间共享而没有问题。如果一条备忘录没有改变,两个人可以同时安全地查看该备忘录。同样,由于类字节代码没有改变,多个线程可以从一个副本同时读取它们。
另一种方法是使用锁来对线程之间的东西进行排序(无论是谁接触鼠标都要使用PC)。例如,您可以想象一个JVM,其中只有一个字节代码解释器,它在所有线程之间共享,并受一个全局锁保护(在实践中效率非常低,但您明白了)。
还有一些其他高级机制可让多个线程使用共享资源。开发JVM的人使用了这些技术,这就是为什么每个线程不需要JVM副本的原因。
答案 1 :(得分:3)
但我不知道没有运行JVM的线程如何处理字节码;是不是所有线程都可以访问JVM?
http://www.artima.com/insidejvm/ed2/jvmP.html很好地解释了这一点。以下是它的说法:
“正在运行的Java应用程序的每个线程都是虚拟机执行引擎的独特实例。从生命周期的开始到结束,线程正在执行字节码或本机方法。线程可以直接执行字节码,通过在硅片中本地解释或执行,或通过及时编译和执行生成的本机代码间接执行字节码.Java虚拟机实现可以使用正在运行的应用程序不可见的其他线程,例如线程这样的线程不需要是实现执行引擎的“实例”。但是,属于正在运行的应用程序的所有线程都是执行引擎。“
总结我对此的理解:
对于每个线程(execpt GC线程和同类),相应的ExecutionEngine实例(在同一个JVM中)将字节码转换为机器指令,本机OS线程执行这些机器指令。当然,我不在这里谈论绿色线索。
答案 2 :(得分:2)
根据定义,Java应用程序中的线程共享相同的内存空间,因此在同一JVM中执行。通过这种方式,您可以轻松地跨多个线程共享对象,执行同步等等,这些都发生在JVM中。
一种看待它的方法是进程有自己的内存空间,而应用程序中的线程共享相同的内存空间。