Java 线程在一段时间后停止更新显示
我试图用JavaFX8做一个神经网络训练可视化。网络单元显示为根据输出值改变颜色的点。计算和绘图在一个线程中完成,可以通过单击按钮启动或停止该线程。有一段时间,一切正常,但经过多次迭代后,显示不再更新 需要做什么才能可靠地更新显示 我使用的是JRE版本1.8.045 以下是我的代码的简化版本:Java 线程在一段时间后停止更新显示,java,javafx,javafx-8,Java,Javafx,Javafx 8,我试图用JavaFX8做一个神经网络训练可视化。网络单元显示为根据输出值改变颜色的点。计算和绘图在一个线程中完成,可以通过单击按钮启动或停止该线程。有一段时间,一切正常,但经过多次迭代后,显示不再更新 需要做什么才能可靠地更新显示 我使用的是JRE版本1.8.045 以下是我的代码的简化版本: import javafx.application.*; import javafx.concurrent.Task; import javafx.geometry.Insets; import java
import javafx.application.*;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.stage.Stage;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.*;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
public class TestView extends Application {
public static final int SCENE_WIDTH = 1000;
public static final int SCENE_HEIGHT = 800;
public static final int BUTTON_PANEL_HEIGHT = 80;
private Canvas canvas;
private GraphicsContext gc;
private Task<Void> task = null;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("MLP");
BorderPane borderPane = new BorderPane();
canvas = new Canvas( SCENE_WIDTH, 3*SCENE_HEIGHT-BUTTON_PANEL_HEIGHT );
gc = canvas.getGraphicsContext2D();
borderPane.setCenter(new ScrollPane(canvas));
GridPane buttonPanel = new GridPane();
Button buttonTrain = new Button("Train");
buttonTrain.setMinWidth(SCENE_WIDTH/2);
buttonPanel.setPadding(new Insets(0, 0, 0, 0));
buttonPanel.add(buttonTrain, 1, 0);
borderPane.setBottom(buttonPanel);
buttonTrain.setOnMouseClicked( e -> {
if (task != null) {
task.cancel();
task = null;
}
else {
task = new Task<Void>() {
@Override
protected Void call() throws Exception {
for (int i = 1; i <= 10000000; i++) {
if (isCancelled()) {
break;
}
// dummy calculation
doSomeStuff();
// dummy graphics update
gc.setFill(Color.GREEN);
gc.fillOval(50, 50, 20, 20);
gc.clearRect(200, 10, 200, 100);
gc.setFill(Color.BLACK);
gc.fillText("" + i, 200, 50);
}
return null;
}
};
new Thread(task).start();
}
});
Scene scene = new Scene( borderPane, SCENE_WIDTH, SCENE_HEIGHT );
primaryStage.setScene(scene);
primaryStage.show();
}
private double doSomeStuff() {
double r = 0.5;
for ( int i = 0; i < 10000; i++ ) {
r = Math.sin(r);
}
return r;
}
}
导入javafx.application.*;
导入javafx.concurrent.Task;
导入javafx.geometry.Insets;
导入javafx.stage.stage;
导入javafx.scene.control.Button;
导入javafx.scene.control.ScrollPane;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.GridPane;
导入javafx.scene.paint.Color;
导入javafx.scene.*;
导入javafx.scene.canvas.canvas;
导入javafx.scene.canvas.GraphicsContext;
公共类TestView扩展了应用程序{
公共静态最终int场景宽度=1000;
公共静态最终int场景_高度=800;
公共静态最终int按钮面板高度=80;
私人帆布;
私有图形上下文gc;
私有任务任务=null;
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
public void start(Stage primaryStage)引发异常{
初级阶段。设置标题(“MLP”);
BorderPane BorderPane=新的BorderPane();
画布=新画布(场景宽度,3*场景高度-按钮面板高度);
gc=canvas.getGraphicsContext2D();
设置中心(新滚动窗格(画布));
GridPane buttonPanel=新建GridPane();
按钮按钮牵引=新按钮(“列车”);
buttonTrain.setMinWidth(场景宽度/2);
设置填充(新的插入(0,0,0,0));
添加(buttonTrain,1,0);
borderPane.setBottom(按钮面板);
buttonTrain.setOnMouseClicked(e->{
如果(任务!=null){
task.cancel();
task=null;
}
否则{
任务=新任务(){
@凌驾
受保护的Void调用()引发异常{
对于(int i=1;i)您正在从FX应用程序线程以外的线程更新UI。这样做时,行为没有定义。我很少使用JavaFX画布,所以我不确定这一点,但我认为您也在将越来越多的命令连接到图形上下文的堆栈中。您可能每次都需要清除gc。@James_D:是的,这似乎是正确的这就是问题所在。我了解到JavaFX中有一个每秒触发60次的事件,负责更新显示。在我的循环中插入线程。sleep(50)
解决了问题。但我仍然想知道是否有更好的解决方案。例如,是的