1

我是多线程、Java 和 JavaFx 的新手。我正在使用 JavaFX UI 构建一个应用程序,它会根据实时数据不断更新图表。这是目前的设计,

1. 当按下 JavaFx 按钮时,我调用一个线程,该线程设置框架以发送请求并获取响应

    startButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override 
        public void handle(ActionEvent e) {             
            stopButton.setDisable(false);               

            if(!startButton.isDisable()){
                runSequence = new Thread(new Runnable(){

                    @Override
                 public void run() {
                    SynchThreads sharedObject = new SynchThreads();             
                    new Bridge(sharedObject);
                    startSequence = new Sequence(sharedObject);             
                    startSequence.performCalls();  

                    }                   
                });

                runSequence.start();

            }               
            startButton.setDisable(true);
        }
    });

2. 如上调用的runSequence线程调用另一个不断接收数据的线程“callbackThread”。接收到的这个数据被传递给 runSequence 线程进行进一步处理

    BusinessLogic businessLogic = new BusinessLogic();

    executor.submit(pduApiDllCallBackThread);//This collects the data in background

//Here we are back on runSequence thread that works on the collected data.  
         while(true){
        response = sharedObject.take();                 
        businessLogic.primeData(response);
    }

3. 处理此数据后的 BusinessLogic 类将事件 ID 和应显示在图表上的数据通知用户界面。

  UI.notifyListeners(0, graphCoords);//here event ID is 0 and graphCoords is a HashMap

4. 在用户界面中,每次收到通知时,我都会使用 Platform.runLater 更新 LineChart。此通知每 4 毫秒发生一次。所以,我最终做了很多 Platform.runLater 调用

public void notifyListeners(int eventType, Map<Integer, Float> graphCoords) {
    Platform.runLater(new Runnable(){

        @Override
        public void run() {
    //Old series is cleared. Showing dummy data being updated
                    series.getData().clear();
        series.getData().add(new XYChart.Data("1", Math.random()+1));
            series.getData().add(new XYChart.Data("3", Math.random()+5));
            series.getData().add(new XYChart.Data("4", Math.random()-25));
            series.getData().add(new XYChart.Data("2", Math.random()-10));
            series.getData().add(new XYChart.Data("-1", xxx));


        }

    });

}

如果可以这样做,或者是否有更好的方法在 UI 中处理此问题,请提供您的专家提示。我对通知 UI 的 UI 下方的层没有更多控制权。由于通知每 4 毫秒发生一次,我想知道是否有更好的方法

任何帮助表示赞赏。请帮忙。谢谢 !

4

1 回答 1

2

您可能会通过经常执行 Platform.runLater 来淹没 JavaFX 事件队列,因此您可能希望对响应进行批处理(例如以十个为一组),然后为每个批处理进行一次 runlater 调用。

stackoverflow 上有一个特定的codereview站点。

确保您在图表上关闭了动画,这样它就不会在每次更新时尝试做太多事情。

您的解决方案似乎有点复杂,但也许它适合您的情况,我不知道。

我不知道您是如何处理并发的,但如果您还没有的话,请查看java.util.concurrent并发教程。如果您还没有,还可以查看JavaFX中的并发。有时,较高级别的java.util.concurrent框架比较低级别的对象监视器等待/通知方法更具表现力、更不容易出错、更易于使用且更易于推理。

您可能希望将您正在使用的一些线程标记为守护线程。您可能还想添加一些逻辑来处理线程中断或进程取消,类似于 JavaFX任务文档中的示例。

如果您是 Java、多线程和 JavaFX 的新手,那么从多线程、网络化的 JavaFX 应用程序开始就是跳出深渊。

通常,使用任务/服务框架将并发工作从 JavaFX 应用程序线程卸载到工作线程。

于 2012-12-21T10:57:25.103 回答