了解JavaFXWebView线程模型
我试图理解JavaFX线程是如何工作的。描述没有多大帮助 例如,在下面的代码中,打印顺序始终是了解JavaFXWebView线程模型,java,multithreading,javafx,Java,Multithreading,Javafx,我试图理解JavaFX线程是如何工作的。描述没有多大帮助 例如,在下面的代码中,打印顺序始终是A然后B然后Z,这表明load()调用和changed()中的代码都在同一线程上运行 但是我不明白,为什么线程不在最后一个线程之后退出。sleep(2000)(因为没有更多的工作要做) 我希望changed()中的代码每次都能在一个新线程上运行,我完全搞不清楚这是如何工作的 public class Test extends Application { @Override public voi
A
然后B
然后Z
,这表明load()
调用和changed()
中的代码都在同一线程上运行
但是我不明白,为什么线程不在最后一个线程之后退出。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);
}
}
公共类测试扩展应用程序{
@凌驾
public void start(Stage)引发异常{
最终WebView WebView=新WebView();
场景=新场景(webView);
舞台场景;
stage.show();
webView.getEngine().getLoadWorker().stateProperty()
.addListener(新的ChangeListener(){
@凌驾
公共无效更改(简短回答)
start()
和changed()
从“JavaFX应用程序线程”运行。此线程负责监视UI中的事件,将它们发送到用户代码并重新绘制UI。与Runnable.run()
不同,退出时线程终止,“JavaFX应用程序线程”调用start()
在类似于循环的情况下:当start()
结束时,将执行下一个迭代(实际上,迭代是异步运行的/等待事件,以便不占用所有CPU资源,但作为简化模型,循环是正常的)
更长的答案
我会尽量解释得更详细一点
将打印语句放置为(无凹入以突出):
应用程序:主窗口出现…但是没有内容!为什么?因为负责绘制UI的“JavaFX应用程序线程”在点“A”之前正在sleep()
-ing
控制台:2秒后打印“A”
应用:仍在为“B”休眠,窗口中仍没有内容
控制台:2秒后打印“B”
应用程序:事情变得生动起来,内容开始填充;UI线程不再被阻塞在sleep()
中,因此它可以自由地执行其工作
请注意,尽管start()
已结束,launch()
未结束,因此主线程处于活动状态,因此应用程序处于活动状态。一段时间后,页面将加载:
控制台:
3:JavaFX应用程序线程
Z
用户操作:按关闭
控制台:
4:main
应用程序:窗口关闭,应用程序退出
要深入了解本主题,您可以在main()
和start()
中放置断点,并观察各种活动线程
注释:用户界面线程中的sleep()
调用观察到的行为就是为什么如果希望应用程序响应,就不能在用户界面线程内执行长时间运行的任务。简而言之:您在用户界面线程上睡眠,因此无法处理任何事件(如将加载工作程序的状态设置为成功)。。。
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());
}