当前位置: 首页 > 面试题库 >

JavaFX中的多线程会挂起UI

袁翰池
2023-03-14
问题内容

我有一个简单的JavaFX
2应用程序,带有2个按钮,分别是“开始”和“停止”。单击开始按钮后,我想创建一个后台线程,该线程将进行一些处理并随着时间的推移更新UI(例如进度条)。如果单击停止按钮,我希望线程终止。

我尝试使用javafx.concurrent.Task从文档中收集的类来完成此操作。但是,每当我单击“开始”时,UI就会冻结/挂起,而不是保持正常。

她是来自主Myprogram extends Application类的用于显示按钮的代码:

public void start(Stage primaryStage)
{               
    final Button btn = new Button();
    btn.setText("Begin");

    //This is the thread, extending javafx.concurrent.Task :
    final MyProcessor handler = new MyProcessor();
    btn.setOnAction(new EventHandler<ActionEvent>()
    {
        public void handle(ActionEvent event)
        {                
           handler.run(); 
        }
    });

    Button stop = new Button();
    stop.setText("Stop");
    stop.setOnAction(new EventHandler<ActionEvent>()
        {
             public void handle(ActionEvent event)
             {
                handler.cancel();
             }
        }

    );
    // Code for adding the UI controls to the stage here.
}

这是MyProcessor类的代码:

import javafx.concurrent.Task;
public class MyProcessor extends Task
{   
    @Override
    protected Integer call()
    {
        int i = 0;
        for (String symbol : feed.getSymbols() )
        {
            if ( isCancelled() )
            {
                Logger.log("Stopping!");
                return i;
            }
            i++;
            Logger.log("Doing # " + i);
            //Processing code here which takes 2-3 seconds per iteration to execute
            Logger.log("# " + i + ", DONE! ");            
        }
        return i;
    }
}

相当简单,但是每当我单击“开始”按钮时UI就会挂起,尽管控制台消息会继续显示(Logger.log只是这样做System.out.println

我究竟做错了什么?


问题答案:

Task实现Runnable,因此当您调用时,handler.run();您实际上call在UI线程中运行该方法。这将挂起UI。

您应该在后台线程中通过执行程序或通过简单调用来启动任务new Thread(handler).start();

在Javadoc或JavaFX并发教程中对此进行了解释(可能不太清楚)。



 类似资料:
  • 我需要在 JavaFX 应用程序的后台使用多个线程。我有一个带有十个按钮的屏幕,我需要将每个线程与启动线程的按钮“绑定”在一起。如果用户按下了启动线程的按钮(在主屏幕中,MainController.java),我需要恢复它以显示包含的信息,以在详细信息屏幕(第二个屏幕,DetailController.java)的控件上显示它。 你推荐什么课程?服务? https://docs.oracle.c

  • 我在JavaFx应用程序中面临一个问题。 前言:我不想具体到我的应用程序,而是想概括,这样像我这样的人就会对类似的情况有所了解。 背景:使用fxml文件和多线程概念实现一个Javafx应用程序。 总结:我试着做了一个应用程序,它基本上使用多线程来做一些任务,一旦多线程完成,它就会依次移动到另一个任务。在执行多线程操作时,主GUI会冻结。 我的所作所为, 现在,结果是这样的。如果我只是从控制器启动线

  • 我有两个交织在一起的多线程问题。 我在使用spring boot的JavaFX桌面应用程序中有一个SplitPane。左边是树视图,右边是选项卡窗格。开始时,SplitPane设备位于右侧边缘,隐藏了TabPane。当用户在树中选择一个项目时,两件事将同时发生: 首先,根据选择,创建10个选项卡。选项卡因所选对象而异。每个选项卡都显示与选定对象相关的详细数据。大多数选项卡包含图表,但也包含文本。

  • 问题内容: 我正在尝试的代码 我们如何根据其ID暂停/暂停线程?Thread.suspend已过时,必须有一些替代方法来实现。我有线程ID,我想挂起并杀死线程。 编辑:我用这个。 但是我无法停止该线程。 问题答案: 这些天杀死线程的正确方法就是使用它。这集真和原因,以及一些其他的方法来扔。 在线程代码内部,您应该执行类似以下的操作,检查以确保它没有被中断。 这是一个如何在线程内部处理中断异常的示例

  • 问题内容: 我正在用javaFx编写天气应用程序,以从openweather.org获取数据。从openweather获取JSON的整个代码运行良好,也可以将JSON数据转换为对象。我用lambda表达式来实现在。问题是:如果我运行Main class,请按按钮,该应用程序将挂起。导入数据的线程有效(在控制台上通过2次打印检查),主线程“跳过” 并在控制台上打印某些内容。我不确定这里出什么问题了。

  • 问题内容: 与此问题相关,我有以下代码可订阅redispubsub队列,并使用__init__中提供的处理程序将消息提供给处理它们的类: 在上面的链接问题中,请注意,如果断开连接,则永不返回。因此,尽管我的函数可以被调用,但它实际上不会导致线程终止,因为它挂在对线程内部的调用上。 链接问题的可接受答案提到了黑客入侵redis-py的连接池。我真的不想这样做,并且有一个分支版本的redis- py(