我试图了解为什么我的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也会冻结,我无法找到问题。
有什么建议吗?
答案 0 :(得分:0)
你的问题很容易解释。 CPU工作非常努力。
让我们假设你有4个核心和6个线程(UIThread + 5个计算线程)。 6个线程必须共享这4个核心。因此,即使是UIThread也需要等待调度程序给他一些CPU时间,这可能需要一段随机的时间。因此,您的UI可能会冻结随机时间长度或直到3个计算线程完成。