繁体   English   中英

Java FX后台线程使GUI冻结

[英]Java FX background threads make GUI freeze

我试图了解为什么在后台线程中运行昂贵的操作时Java FX应用程序冻结了。 这是我的课:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class TestApp extends Application {

public static void main(String[] args) {
    launch(args);
}

@Override
public void start(Stage primaryStage) throws Exception {
    primaryStage.setTitle("Test Threads");
    // create grid for the form
    GridPane grid = new GridPane();
    grid.setAlignment(Pos.TOP_CENTER);
    grid.setHgap(10);
    grid.setVgap(10);
    grid.setPadding(new Insets(25, 25, 25, 25));

    TextField tf = new TextField();
    grid.add(tf, 0, 0);

    Button runButton = new Button("Run");
    grid.add(runButton, 0, 1);
    runButton.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent e) {
            System.out.println(Thread.currentThread() + ": starting threads");
            for (int i=0;i<5;i++){
            Task<Integer> task = new Task<Integer>() {

                @Override
                public Integer call() {
                    Random rand = new Random();
                    List<Integer> numbers = new ArrayList<Integer>();

                    for (int i=0; i<20000000; i++){
                        numbers.add(rand.nextInt());
                    }
                    System.out.println(Thread.currentThread() + ": generated");

                    return numbers.size();
                }
            };
            new Thread(task).start();
            }
            System.out.println(Thread.currentThread() + ": started all threads.");
        }
    });

    StackPane root = new StackPane();
    root.getChildren().add(grid);
    primaryStage.setScene(new Scene(root, 500, 420));
    primaryStage.show();
}

}

当按下“运行”按钮时,将创建并启动五个后台线程。 所有线程运行并生成每个具有20000000整数的列表。 即使这些操作在其他线程上运行,GUI仍然冻结,我无法找到问题。

有什么建议么?

您的问题很容易解释。 CPU真的很努力。

假设您有4个核心和6个线程(UIThread + 5个计算线程)。 6个线程必须共享这4个内核。 因此,即使UIThread也需要等待调度程序给他一些CPU时间,这可能需要随机的时间。 因此,您的UI可能会冻结随机的时间长度,或者直到3个计算线程结束。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM