簡體   English   中英

Java退出程序而不退出JVM

[英]Java exit a program without quitting JVM

如果要滿足某個條件,我想退出Java進程並釋放所有資源,直到它完成其正常運行。 但是,我不想退出JVM,因為我同時運行其他Java程序。 確實return; 做到以上幾點,還是有更好的方法呢?

謝謝。

每個運行的Java應用程序都有一個JVM進程。 如果退出該應用程序,則進程的JVM將關閉。 但是,這不會影響其他Java進程。

您需要了解JVM機制並闡明術語。

讓我們將以下內容用作術語的基准。

  • 線程是進程中同時處理的流的划分。

  • 進程是操作系統級別的線程。 操作系統管理進程。 通過向OS管理發送終止信號來終止進程。 信號可以由進程本身或具有適用特權的另一個進程發送。

  • 在流程內,您可以創建流程級線程。 進程級別線程通常通過OS的進程管理來促進,但是它們由進程啟動,並由進程終止。 因此,進程級線程與進程不同。

  • 應用程序是以各種形式協作的系統,程序和/或線程的集合。 應用程序中的程序或進程可以終止而不會終止整個應用程序。

在JVM術語的上下文中,程序可以是以下之一。

  • 每個JVM進程都會運行一個程序。 每個程序消耗一個JVM進程,並通過提供Java字節碼的類路徑並指定在類路徑中找到的主要入口點來調用。 當您終止Java程序時,運行該程序的整個jvm進程也會終止。

  • 每個進程級線程都會運行一個程序。 例如,在tomcat或JEE服務器中運行的應用程序在JEE進程中作為線程運行。 JEE進程本身就是一個消耗一個JVM進程的程序。 終止應用程序時,JEE進程不會終止。

您可以在Java程序中啟動進程級線程。 您可以編寫終止線程但不會終止進程的代碼(除非它是進程中的最后一個也是唯一正在運行的線程)。 JVM垃圾回收將負責釋放資源,並且在進程級線程終止后,您無需自己釋放資源。

為簡化理解,簡化了以上響應。 請仔細閱讀OS設計和線程,以促進對進程和JVM機制的更好理解。

如果同時運行的其他線程不是守護程序線程,則離開main不會終止VM。 其他線程將繼續運行。

我完全錯了。

如果在單獨的JVM中啟動每個程序,則在其中一個中調用System.exit()不會影響其他程序,它們是完全不同的過程。

如果您是通過單個腳本或其他方式啟動它們,則取決於其編寫方式,那么其他方式可能會殺死其他進程。 如果沒有有關如何啟動這些應用程序的准確信息,則實際上是無法告訴發生了什么。

@aix的答案可能與您的問題有關。 每次您運行java命令(或等效命令)時,都會得到一個不同的JVM實例。 在一個JVM實例中調用System.exit()不會導致其他JVM實例退出。 (試試看!)

可以創建一個框架,在其中您可以在同一JVM中運行多個程序。 實際上,這實際上是您在運行“ bean shell”時所做的事情。 當您的“程序”是在某些應用程序服務器框架中運行的服務(或Web應用程序,或您所謂的它們)時,會發生同樣的事情。

壞消息是,如果您做這種事情,沒有完全可靠的方法可以使單個“程序”消失。 特別是,如果程序不是設計為協作的(例如,如果它不檢查中斷),則必須訴諸DEPRECATED Thread.stop()方法和朋友。 這些方法可能會對JVM和其中運行的其他程序造成不良后果。

從理論上講,解決該問題的方法是使用隔離。 不幸的是,我不認為任何主流JVM都支持隔離。

可以通過Nailgun或Drip之類的工具解決導致此類需求的一些常見用例。

Nailgun允許您運行似乎是命令行程序的多個獨立執行的程序,但是它們都發生在同一JVM中。 因此,不必忍受重復的JVM啟動時間。 如果這些執行與全局狀態交互,那么JVM將及時受到污染,事情開始崩潰。

Drip每次執行都會使用一個新的JVM,但是它始終保持預先創建的JVM具有正確的類路徑和選項。 這性能較低,但是可以通過隔離來保證正確性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM