Moe*_*oeb 5 java multithreading javafx
我试图了解 JavaFX 线程是如何工作的。这里的描述没有多大帮助。
例如,在下面的代码,印刷的顺序总是A然后B然后Z,这表明,无论是load()呼叫和里面的代码changed()都在同一线程上运行。
但是我不明白,为什么线程不会在最后一个之后退出Thread.sleep(2000)(因为没有更多的工作要做)?
我希望里面的代码changed()每次都在一个新线程上运行,并且完全不知道这是如何工作的!
public class Test extends Application {
@Override
public void start(Stage stage) throws Exception {
final WebView webView = new WebView();
Scene scene = new Scene(webView);
stage.setScene(scene);
stage.show();
webView.getEngine().getLoadWorker().stateProperty()
.addListener(new ChangeListener<State>() {
@Override
public void changed(ObservableValue<? extends State> ov, State t, State t1) {
if (t1 == Worker.State.SUCCEEDED) {
System.out.println("Z"); // <---
}
}
});
webView.getEngine().load("http://www.google.com");
System.out.println("A"); // <---
Thread.sleep(2000);
System.out.println("B"); // <---
Thread.sleep(2000);
}
public static void main(String[] args) {
launch(args);
}
}
Run Code Online (Sandbox Code Playgroud)
start()并changed()从“JavaFX应用程序线程”运行。该线程负责监视 UI 中的事件,将它们分派给用户代码并重新绘制 UI。与退出时不同Runnable.run(),线程终止,start()由“JavaFX 应用程序线程”以类似循环的方式调用:当start()结束时,执行下一次迭代。(实际上迭代是异步运行/等待事件,以免消耗所有 CPU 资源,但作为简化模型,循环是可以的。)
我会尝试更详细地解释一下。
将打印语句放置为(未缩进以突出):
public void start(Stage stage) throws Exception {
System.out.println("2: " + Thread.currentThread().getName());
...
webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
@Override
public void changed(ObservableValue<? extends State> ov, State t, State t1) {
if (t1 == Worker.State.SUCCEEDED) {
System.out.println("3: " + Thread.currentThread().getName());
System.out.println("Z"); // <---
}
}
});
webView.getEngine().load("...");
System.out.println("A"); // <---
Thread.sleep(2000);
System.out.println("B"); // <---
Thread.sleep(2000);
}
public static void main(String[] args) {
System.out.println("1: " + Thread.currentThread().getName());
launch(args);
System.out.println("4: " + Thread.currentThread().getName());
}
Run Code Online (Sandbox Code Playgroud)
观察控制台和应用程序:
用户操作:启动应用程序
控制台:立即显示以下内容:
public void start(Stage stage) throws Exception {
System.out.println("2: " + Thread.currentThread().getName());
...
webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
@Override
public void changed(ObservableValue<? extends State> ov, State t, State t1) {
if (t1 == Worker.State.SUCCEEDED) {
System.out.println("3: " + Thread.currentThread().getName());
System.out.println("Z"); // <---
}
}
});
webView.getEngine().load("...");
System.out.println("A"); // <---
Thread.sleep(2000);
System.out.println("B"); // <---
Thread.sleep(2000);
}
public static void main(String[] args) {
System.out.println("1: " + Thread.currentThread().getName());
launch(args);
System.out.println("4: " + Thread.currentThread().getName());
}
Run Code Online (Sandbox Code Playgroud)
应用程序:出现主窗口...但是没有内容!为什么?因为负责绘制 UI 的“JavaFX 应用程序线程”sleep()在点“A”之前是 -ing。
控制台:2秒后打印“A”
应用程序:仍在休眠“B”,窗口中仍然没有内容
控制台:2秒后打印“B”
应用程序:事物变得栩栩如生,内容开始填充;UI 线程不再被阻塞,sleep()因此它可以自由地执行其工作。
请注意,尽管事实start()已经结束,launch()但不是,因此主线程仍然处于活动状态并且运行良好,因此应用程序处于活动状态。过了一会儿,页面加载完毕:
安慰:
1: main
2: JavaFX Application Thread
Run Code Online (Sandbox Code Playgroud)
用户操作:按关闭
控制台:
3: JavaFX Application Thread
Z
Run Code Online (Sandbox Code Playgroud)
应用程序:窗口关闭,应用程序退出
为了更深入地了解本主题,您可以在main()和中放置断点start()并观察各个活动的线程。
评论:从 UI 线程中的调用中观察到的行为sleep()就是为什么如果您希望应用程序具有响应能力,则决不能在 UI 线程内执行长时间运行的任务。
| 归档时间: |
|
| 查看次数: |
1575 次 |
| 最近记录: |