Dav*_*son 2 java multithreading javafx-8
我正在尝试使用 JavaFX 运行程序。如果我使用 Swing,我会用 main 方法启动一个类,并让它构建 GUI 类。这会给我 2 个线程,应用程序的普通线程和 EventQueue。这将防止阻止 UI 工作。
因此,我尝试让在静态 main 方法中创建的类构造 Application 类,然后启动它。我得到了一个 RuntimeException,因为调用 launch 方法的程序不是 Application 的子类。
有没有办法分离线程,或者一切都必须在给定 Application 类的线程内工作?
在 JavaFX 中,我猜为了防止许多 Swing 应用程序中出现的非常常见的线程错误,启动过程受到限制,以便(或多或少)唯一的做事方式迫使您执行 UI 代码外汇应用线程:
public class MyAppStartClass extends Application {
@Override
public void start(Stage primaryStage) {
// this method will be executed on the FX Application Thread
// load UI and display it here....
}
}
Run Code Online (Sandbox Code Playgroud)
在 Oracle JRE 中,执行java MyAppStartClass将(与常规 Java 应用程序相反)导致MyAppStartClass创建一个实例,启动 FX 应用程序线程,并start在 FX 应用程序线程上执行创建的实例的方法。(除此之外还有更多内容,但这是基本要点。)
如果您想支持不知道如何执行 JavaFX 应用程序(包括许多 IDE)的环境,您可以添加一个main强制执行此操作的方法,只需调用静态Application.launch()方法:
public class MyAppStartClass extends Application {
@Override
public void start(Stage primaryStage) {
// this method will be executed on the FX Application Thread
// load UI and display it here....
}
// to support non-JavaFX-aware environments:
public static void main(String[] args) {
launch(args);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,有一个 的重载形式launch,您可以在其中指定一个Application子类,因此您可以拥有一个不同的主类(此用例很少):
public class MainClass {
public static void main(String[] args) {
Application.launch(MyAppStartClass.class, args);
}
}
Run Code Online (Sandbox Code Playgroud)
该方法有两个重要特征launch需要注意:
如果你想让一个线程在 FX Application Thread 之外做工作,最简单的方法是直接从 start 方法启动它:
public class MyAppStartClass extends Application {
@Override
public void start(Stage primaryStage) {
// start a background thread to do background stuff:
new Thread(() -> {
// background work...
}).start();
// UI work...
}
}
Run Code Online (Sandbox Code Playgroud)
如果将其与 Swing 应用程序的标准启动进行比较:
public class MySwingApp {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
// UI work...
});
// background work...
}
}
Run Code Online (Sandbox Code Playgroud)
与 Swing 相比,这个过程有点颠倒。在 Swing 中,您(应该)明确地让启动方法 (main) 指定 UI 在 AWT 事件调度线程上运行,并且您可以在执行 main 的“当前”线程中执行其他操作。在 JavaFX 中,启动方法 (start) 是在 UI 线程上执行的,如果您想在另一个线程上执行操作,您可以显式启动一个。
其他规则几乎相同:作为场景图一部分的 UI 元素只能在 UI 线程等上进行修改。 注意 JavaFX 有一个特定的并发 API,用于管理后台线程中的任务并在 FX 应用程序上调度 UI 更新线。
在旁边:
从理论上讲,我想您可以执行以下操作:
public class MainClass {
public static void main(String[] args) {
new Thread(() -> Application.launch(MyAppStartClass.class, args)).start();
// do "background thread" work here in the (now free) main thread
}
}
Run Code Online (Sandbox Code Playgroud)
但由于该习语与通常的设置相去甚远,我不推荐它。尤其要注意,您不应该直接在Application子类中使用这样的 main 方法,因为(我认为)Oracle JRE(或知道如何运行 JavaFX 应用程序的环境)可能会忽略 main 方法并按照描述启动您的 start 方法在这篇文章的顶部。
| 归档时间: |
|
| 查看次数: |
3184 次 |
| 最近记录: |