Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
了解JavaFXWebView线程模型_Java_Multithreading_Javafx - Fatal编程技术网

了解JavaFXWebView线程模型

了解JavaFXWebView线程模型,java,multithreading,javafx,Java,Multithreading,Javafx,我试图理解JavaFX线程是如何工作的。描述没有多大帮助 例如,在下面的代码中,打印顺序始终是A然后B然后Z,这表明load()调用和changed()中的代码都在同一线程上运行 但是我不明白,为什么线程不在最后一个线程之后退出。sleep(2000)(因为没有更多的工作要做) 我希望changed()中的代码每次都能在一个新线程上运行,我完全搞不清楚这是如何工作的 public class Test extends Application { @Override public voi

我试图理解JavaFX线程是如何工作的。描述没有多大帮助

例如,在下面的代码中,打印顺序始终是
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());
    }