gpt4 book ai didi

JavaFX TextArea appendText CPU 使用率高

转载 作者:行者123 更新时间:2023-12-02 02:14:31 25 4
gpt4 key购买 nike

我正在开发一个 JavaFX 终端应用程序,它可以高速显示来自串行端口的文本。我正在使用 TextArea 控件来显示和管理文本。对于来自串行端口的每个文本 block ,我使用appendText 函数将文本添加到终端。将文本更新到 TextArea 时,我遇到性能问题(CPU 使用率高)。以下代码模拟了该问题,CPU 使用率从 15%-30% 变化,这对于简单的 appendText 更新来说相当高:

public class Main extends Application {
ExecutorService executor = Executors.newFixedThreadPool(1);
@Override
public void start(Stage primaryStage) {
AnchorPane root = new AnchorPane();
TextArea textArea = new TextArea();
AnchorPane.setTopAnchor(textArea, 0.0);
AnchorPane.setBottomAnchor(textArea, 0.0);
AnchorPane.setLeftAnchor(textArea, 0.0);
AnchorPane.setRightAnchor(textArea, 0.0);
root.getChildren().add(textArea);
textArea.setCache(true);
textArea.setCacheShape(true);
textArea.setCacheHint(CacheHint.SPEED);
Runnable runnableTask = () -> {
while (true) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
Platform.runLater(() -> {
textArea.appendText("The easiest way to create ExecutorService is to use one of the factory methods\n");
while(textArea.getText().split("\n", -1).length > 500) {
int firstLineEndIndex = textArea.getText().indexOf("\n");
textArea.replaceText(0, firstLineEndIndex+1, "");
}
});
}
};
primaryStage.setTitle("TextArea performance");
primaryStage.setScene(new Scene(root, 1000, 800));
primaryStage.show();
executor.execute(runnableTask);
}
public static void main(String[] args) {
launch(args);
}
}

谁能解释一下为什么CPU使用率这么高?有办法减少吗?谢谢!!!**

最佳答案

首先,你每秒做这些事情二十次。这可不是小事。

其次,你所做的不仅仅是appendText。对于 runLater 方法内的 while 循环的每次迭代,您都会一次又一次地对 TextArea 的整个文本调用 split。正则表达式是昂贵的操作。以下是将文本限制为最后 500 行的更有效方法:

String text = textArea.getText();
String[] lines = text.split("\n", -1);
if (lines.length > 500) {
lines = Arrays.copyOfRange(lines,
lines.length - 500, lines.length);
text = String.join("\n", lines);
textArea.setText(text);
}

与您的CPU问题无关,您编写了一个流氓线程:它忽略中断。中断是其他代码向您的线程发出的显式请求,要求其停止正在执行的操作并正常退出。有一个非常简单的方法可以做到这一点:将 while 循环放在 try block 内:

try {
while (true) {
Thread.sleep(50);
Platform.runLater(() -> {
textArea.appendText("The easiest way to create ExecutorService is to use one of the factory methods\n");
// etc.
});
}
} catch (InterruptedException e) {
e.printStackTrace();
}

或者,由于您使用的是 ExecutorService 而不是简单的 Executor,因此您可以创建 Callable 而不是 Runnable,并使用 ExecutorService.submit而不是执行,所以你根本不需要 try/catch:

Callable<Void> runnableTask = () -> {
while (true) {
Thread.sleep(50);
Platform.runLater(() -> {
// ...
});
}
};

// ...

executor.submit(runnableTask);

关于JavaFX TextArea appendText CPU 使用率高,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49479947/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com