2017-03-04 68 views
4

所以IM使用shutdownhook清理,芽因爲它並不總是保證shutdownhooks線程執行,我應該按這個代碼到JavaFX應用程序線程(方法停止()),它執行每次我關閉我的應用程序?如果沒有關閉,運行其基本上關閉的套接字的代碼並不昂貴,如果沒有關閉,則會終止進程。使用JavaFX Application.stop()在Shutdownhook方法

難道是很好的做法,在ShutdownHook使用Application.stop()來清理?從文檔

報價:

該方法被調用時,應用程序應該停止,並提供了一個 方便的地方爲應用程序退出做準備,摧毀 資源。由 應用程序類提供的這種方法的實現什麼也不做。

注意:此方法被調用JavaFX應用程序線程。

是這種方法只用於清理UI的資源?到目前爲止,我沒有看到使用shutdownhook stop()的理由。

回答

10

stop()只有在您通過Platform.exit()(或者如果Platform.implicitExit爲真,最後一個窗口關閉時)退出應用程序時纔會被調用。如果調用System.exit(),或者運行JVM的本機進程被中斷(例如類似於nix的OS上的ctrl-C),則除了退出JavaFX應用程序的常用方式之外,還會執行關閉鉤子。

stop()在FX應用程序線程上執行,因此訪問UI元素(例如顯示「保存未保存的更改」對話框等)是安全的。關閉鉤子在後臺線程中運行,因此無法訪問UI元素(事實上,FX Toolkit可能會在該階段停止運行)。

所以選擇取決於使用情況。

爲了使這個多一點具體的,這裏有一個快速的測試類:

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.geometry.Insets; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.layout.HBox; 
import javafx.stage.Stage; 

public class ShutdownTest extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     Button platformExit = new Button("Platform Exit"); 
     platformExit.setOnAction(e -> Platform.exit()); 
     Button systemExit = new Button("System Exit"); 
     systemExit.setOnAction(e -> System.exit(0)); 
     Button hang = new Button("Hang"); 
     hang.setOnAction(e -> {while(true);}); 
     HBox root = new HBox(5, platformExit, systemExit, hang); 
     root.setPadding(new Insets(20)); 
     root.setAlignment(Pos.CENTER); 
     Scene scene = new Scene(root); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 

    } 

    @Override 
    public void stop() { 
     System.out.println("Stop"); 
    } 

    public static void main(String[] args) { 
     Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Shutdown hook"))); 
     launch(args); 
    } 
} 

我測試了在Mac OS X

通過「平臺退出」退出按鈕,通過關閉窗口,或者通過右鍵單擊Dock並選擇「Quit」將執行stop()方法和關機掛鉤。

退出「系統退出」按鈕,強制進程退出「活動監視器」,或者通過從命令行中終止進程kill id,將僅執行關閉掛接。通過按下「掛起」按鈕掛起應用程序,然後右鍵單擊Dock並選擇「強制退出」,結果相同。

通過向進程(命令行中的kill -9 idkill -SIGKILL id)發送SIGKILL來執行退出,並且既不執行stop()方法也不執行關閉掛接。那麼這個答案

+0

你只是讓我不知道如果我將永遠使用的stop()在所有關閉一些重要的資源,因爲我可以強行殺死我的過程,當我看到所有的不叫,有碰撞可能相同。感謝您的快速回答。 –

+3

@TomasBisciak絕大多數JavaFX應用程序不會調用'System。exit()'(你應該永遠支持'Platform.exit()')並且不能從命令行運行(減少中斷的可能性),所以通常'stop()'就足夠了。但是,這又取決於你的用例。 –