2012-03-15 86 views
3

我想弄清楚JVM如何在产生多个线程方面工作。我认为我的思维模型可能稍微有些偏差,但现在我被困在了这个想法上:由于任何时候只有一个运行JVM的副本,每个线程都不需要它自己的JVM副本吗?我意识到一个Java应用程序的多个线程被映射到本地操作系统线程,但我不明白没有运行JVM的线程正在处理字节码;是不是所有的线程都有权访问JVM?谢谢,任何帮助表示赞赏。每个线程都不需要它自己的JVM副本吗?

+0

据我所知:。线程=都在同一个JVM实例,处理各种情况下 - HTTP:/ /docs.oracle.com/javase/tutorial/essential/concurrency/procthread.html或http://www.vogella.de/articles/JavaConcurrency/article.htm l#concurrency_processthreads – zapl 2012-03-15 00:43:35

+0

*“因为任何时候只有一个运行JVM的副本”* - >你从哪里得到这些信息?一般情况并非如此。 – 2012-03-15 00:50:00

+0

@BrunoReis当然,我的意思是每个进程只有一个JVM。 – worker1138 2012-03-15 02:02:57

回答

3

这是一个有点过于简单和一些我写的是不是完全正确,但本质上是这样的:

因为在JVM中只有一个副本在任何时间运行,不会每个线程都需要自己的JVM副本?

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

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

但这不是唯一的方法。例如,不可变资源(如内存中的类字节代码)可以在多个线程之间共享,而不会通过共享内存出现问题。如果一张备忘录没有改变,两个人都可以同时安全地查看该备忘录。同样,因为类字节代码不会更改,所以多个线程可以同时从一个副本读取它们。

另一种方法是使用锁定来排列线程之间的事情(无论是谁触摸鼠标以使用PC)。例如,您可以想象一个JVM,其中只有一个字节代码解释器在所有线程之间共享,并受一个全局锁的保护(实际上这会非常低效,但您明白了)。

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

2

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

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

3

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

http://www.artima.com/insidejvm/ed2/jvmP.html解释了这一点。以下是它所说的内容:

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

总结我的这种认识:

对于每一个线程(execpt GC线程和之流),对应ExecutionEngine实例(在同一JVM)将字节码到机器指令和本地OS线程执行的机器指令当然,我这里谈论绿色线程

+0

不错,所以这意味着JVM将同时运行多个执行引擎实例 – xxmajia 2016-06-24 12:52:08

+0

是的,除了GC线程之类的线程不执行任何字节码处理。 – Amit 2016-06-25 07:16:53

相关问题