2009-12-11 64 views
41

如何區分正在運行的Java線程和本機線程?區分Java線程和OS線程?

在Linux中有將是每一個孩子的過程父進程,他們說0是全過程的父母,會不會有所有的派生的Java線程的父線程?

如何知道哪個Java線程與OS線程相關(如果Java線程阻塞了本機進程線程)。

是否有任何Java線程和操作系統線程的命名約定?

運行中的Java線程可以被掛起或從另一個Java代碼中殺死嗎?

+0

Stephen C,我正在學習Linux線程命名和Java線程命名是如何相互關聯的。而且,如何在Linux內管理JVM線程管理。 – karthi 2009-12-14 06:28:02

回答

61

在Linux上,Java線程是使用本機線程實現的,因此使用線程的Java程序與使用線程的本機程序沒有區別。 「Java線程」只是屬於JVM進程的線程。

在一個現代的Linux系統(一個使用NPTL),屬於一個進程的所有線程具有相同的進程ID和父進程ID,但不同的線程ID。您可以通過運行ps -eLf來查看這些ID。 PID列是進程ID,PPID列是父進程ID,LWP列是線程(LightWeight進程)ID。 「主」線程具有與進程ID相同的線程ID,並且其他線程將具有不同的線程ID值。

舊版本的Linux系統,可以使用「的linuxthreads」線程實現,這是不完全符合POSIX標準,而不是選擇NPTL。在linuxthreads系統上,線程具有不同的進程ID。

您可以檢查您的系統是否使用NPTL或Linux線程通過運行系統的C庫(libc)作爲一個獨立的程序,並在其下輸出「可用的擴展」尋找。它應該提到「本地POSIX線程庫」或linuxthreads。到C庫中的路徑改變因系統:它可以是/lib/libc.so.6/lib64/libc.so.6(在64位爲基礎的RedHat系統中),或者類似的東西/lib/x86_64-linux-gnu/libc.so.6(現代基於Debian的系統如Ubuntu)。

在操作系統級別,它們沒有名稱;那些只存在於JVM中。

pthread_kill()pthread_kill() C函數可以用來發送一個信號給特定的線程,你可以用它來試圖從JVM之外殺死那個特定的線程,但是我不知道JVM如何響應它。它可能會殺死整個JVM。

+0

感謝Wyard,我可以命名正在運行的線程並查詢正在運行的線程的詳細信息嗎?我從調試的角度來問。 – karthi 2009-12-14 11:09:56

+0

線程的「名稱」是特定於Java的;看到你必須用調試器連接到JVM的那種信息。從JVM外部,您只能看到它的數字ID,這是它從POSIX角度來看的唯一標識符。 – Wyzard 2009-12-15 02:53:56

+0

在Shell提示符下顯示Java線程名稱應該怎麼做? 如果我將Profiler或Debugger附加到正在運行的JVM,我將能夠獲得正在運行的Java線程名稱並提供給Shell腳本嗎? – karthi 2009-12-15 06:40:40

8

沒有標準;這完全取決於你正在使用的Java實現。另外,不要混淆「本地線程」和「本地進程」。進程是一個孤立的實體,它不能看到其他進程的地址空間。線程是在本地進程的地址空間中運行的東西,它可以看到同一進程的其他線程的內存。

在Linux上看到的是別的東西:有些版本的Linux創建進程表中的父進程的每個線程的條目。這些「過程」不是真正的過程(從隔離意義上講)。它們是可以通過ps命令列出的線程。您可以使用父PI​​D(PPID)找到創建它們的過程。

4

沒有通用的解決方案,Java線程如何映射到操作系統線程(如果有的話)。每個JVM實現都可以用不同的方式來完成。

還有一個純Java線程實現,稱爲green threads。如果原生線程不受支持或者系統根本不是多線程的,則將其用作後備。你不會在你的操作系統上看到任何綠色的線程。

運行中的Java線程可以被掛起或從另一個Java代碼中殺死嗎?

如果它們在同一個JVM上運行,那麼使用stop()。但這不是一個好的解決方案,可能工作,或者不行。 interrupt()允許線程安全地關閉。

無法殺死我知道的JVM之外的線程。如果一個操作系統真的支持殺死線程,我不希望Java應用程序在以後能正常運行!

5

運行Java線程可以是 暫停或從另一個Java 代碼殺死?

理論上是。在實踐中,Thread.kill()Thread.suspend()方法已被棄用,因爲它們在非常有限的情況下是不安全的。基本的問題是,殺死或暫停Java線程可能會干擾依賴它的其他線程,以及可能在更新過程中共享的數據結構。

如果「另一個Java代碼」意味着另一個JVM,那麼它的工作機會就更小了。即使你想出瞭如何發送相關的線程信號,結果也是完全不可預測的。我敢打賭,「目標」JVM會崩潰。

+0

您只需從Java代碼執行Linux命令即可殺死在特定JVM下運行的特定線程。你甚至可以在Windows上執行此操作。但我想你可能是正確的,只會導致該線程的父母JVM崩潰。如果你控制這兩個程序,你應該開發一些IPC調用來告訴另一個進程中的線程無故停止。 – PSIXO 2014-07-03 16:52:00