简体   繁体   中英

Java FX background threads make GUI freeze

I am trying to understand why my Java FX app is freezing when running costly operations in background threads. This is my class:

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();
}

}

Five background threads are created and started when button "Run" is pressed. All the threads run and generate lists with 20000000 integers each. Even though these operations run on other threads, the GUI freezes and I am unable to find the problem.

Any suggestions?

Your problem is very simple to explain. The CPU is working really hard.

Lets assume you have 4 cores and 6 Threads (UIThread + 5 compute threads). The 6 Threads have to share those 4 cores. So even the UIThread needs to wait for the scheduler to give him some CPU time and that can take a random amount of time. So your UI may freeze for random time lengths or until 3 compute threads finished.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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