2012-03-15 108 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

相關問題