2010-04-21 83 views
5

到目前爲止,我使用我的應用程序作爲獨立產品。所以,當用戶按下「停止」按鈕時,我打電話給System.exit(0);,這很好。如何以安全的方式關閉我的軟件?

現在我的應用程序將從另一個程序調用(以編程方式)。所以,我擔心System.exit(0);不僅會殺死我的進程,還會殺死啓動我的程序的外部軟件。

那麼,如果收到來自外部軟件的相應請求,關閉我的應用程序的正確方法是什麼?我的應用是一個GUI應用程序。所以,我想關閉窗口,但我也想關閉我的程序執行的所有進程。

新增:

更具體地講,我想附近我的程序發表的所有主題。我的程序不啓動任何OS進程或任何其他程序。

+0

@Roman:*由我的程序執行的進程*你是指你的Java程序正在運行的所有線程,或者你的程序產生了其他可執行文件(Un * x shell進程,.exe,其他在他們的虛擬機中運行Java程序,無論)? – SyntaxT3rr0r 2010-04-21 16:01:35

+0

@WizardOfOdds,我的意思是「我的Java程序正在運行的所有線程」。 – Roman 2010-04-21 16:07:24

+1

你的程序如何被調用?是否有一種方法被一個已經運行的Java程序調用,所以這兩個程序有效地成爲一個程序?或者是另一個程序進行系統調用來啓動一個新的Java VM與您的程序? – 2010-04-21 16:25:24

回答

0

只要程序沒有與其他人共享應用程序服務器,通過調用System.exit(0)來關閉虛擬機即可終止所有線程。

Javadoc System.exit終止當前運行的Java虛擬機)

編輯: 如果你想要做一些清理關閉之前的代碼,http://java.sun.com/j2se/1.4.2/docs/guide/lang/hook-design.html

+0

@stacker,你的意思是'System.exit(0)'將關閉所有線程,包括外部軟件的線程(啓動我的程序)。 – Roman 2010-04-21 16:18:08

+1

它會殺死JVM。所以如果外部軟件通過產生一個Java進程來啓動你的程序,那就沒問題了。如果外部軟件是簡單地創建類的實例並運行它們的Java代碼,那麼該外部代碼也將被終止。 – 2010-04-21 16:37:02

2

如果你推出的螺紋仍然處理然後調用System.exit(0)將導致他們被殺害。在某些情況下,這會使應用程序處於不一致的狀態。想象一下,該線程正在保存一個文件。

你應該確保在調用System.exit之前,你的線程都是'快樂'死去的。

一種可以用於長時間運行的線程的技術是中毒。要做到這一點,你可以給線程發送一條消息,告訴他們現在應該優雅地死去 - 即一個poson消息。一旦它們全部死亡,可以安全地調用System.exit(0)來終止Swing事件處理線程。

有許多不同的中毒方法,你可以設置一個全局標誌變量,線程檢查它們是否中毒,或者你可以使用Java 5線程庫。看看這個的Javadoc例如,你會發現這種技術的引用:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html

0

上有「一個尺寸適合所有人」的答案,這這是一個簡易替換的系統不幸的是,退出。

您通常需要設置某種標誌,向您的所有線程發出信號,表示該退出時間,並確保他們定期檢查該標誌。這樣可以讓他們在不突然停頓的情況下優雅地清理乾淨,並且確保效果僅限於您自己的組件。在這種情況下,應用程序的主線程也會觀察該標誌,等待所有「worker」類型的線程完成,然後返回到堆棧,直到到達應用程序的入口點。

這個問題與過時的Thread.stop(etc)方法沒有太大差別,特別是關於用更尊重的東西替換System.exit。在這種情況下,why is Thread.stop() deprecated page可能是有用的閱讀。

拋出一個異常(一種叫做ApplicationStopException的自定義異常)來展開主線程的堆棧並不是一個壞主意;這可以防止您必須在整個代碼中處理特殊邏輯,而是讓「消息」傳播到更高級別,在那裏他們可以採取任何需要的操作來優雅地退出程序。

0

我建議你做標誌停止線程,以便線程知道什麼時候必須停止。對於GUI和窗口,您可以調用frame.dispose()。

對於System.exit(),我認爲它不會影響調用者,您可能會嘗試查看真正的效果,但正如其他人已經推薦的那樣,不要直接調用它,只需讓線程停止本身就是