【发布时间】:2021-07-23 10:42:43
【问题描述】:
我需要使用两个线程将两个不同的字符附加到同一个 JavaFX TextArea。我可以让一个工作,但是当我添加第二个线程时,它会因一些很长的异常而中断。我做错了什么?
我查看了这个问题以寻求指导,它让我有一个线程工作,但不是两个: Display output of two different Threads in two separate JavaFx TextArea's
package application;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
TextArea textArea = new TextArea();
textArea.setWrapText(true);
root.setCenter(textArea);
textArea.setText("");
new Thread(() -> PrintChar(textArea, 'a', 100)).start();
new Thread(() -> PrintChar(textArea, 'b', 100)).start();
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
private void PrintChar(TextArea textArea, char letter, int numb)
{
for(int i = 0; i < numb; ++i)
{
textArea.appendText(letter + "");
}
}
}
【问题讨论】:
-
UI 由单线程控制,不是线程安全的。要从您需要使用
Platform.runLater(() -> {textArea.appendText(letter + "");});的任何其他线程编辑 UI,请注意如何将从另一个线程更新 UI 的代码放在括号内。如果您不这样做,那么如果不同的线程尝试同时与同一事物交互,您将遇到各种问题。通过使用 runLater,更新被安排为一次一个,因为 UI 线程能够管理它们,同时还管理用户交互。 -
@sorfiend,感谢您的回复。问题是懒惰的老师从不同版本的教科书中给出了这个作业。学生所拥有的不包括多线程。她发布了她想要做的事情,并说应该可以使用她在 20 分钟视频中介绍的工具来完成。视频中没有你说的内容:(
-
我查看了其他线程,但它并没有很好地回答我的问题。同步如何与它一起工作?
-
同步是一个完全不同的主题,而不是您在场景中需要的东西,因为 UI 线程会正确管理它。当多个线程访问相同的数据时,同步很重要,但是使用
Platform.runLater可以为 javafx 解决这个问题。对于非 UI 相关的代码,它需要一种完全不同的方法,一种方法是谨慎使用volatile变量和事件队列。我强烈推荐关注官方教程,它有一些很棒的信息:docs.oracle.com/javase/tutorial/essential/concurrency/… -
为什么你认为你需要并发?这是一项很可能可以使用单线程完成的学校作业,尤其是因为你还没有学过并发
标签: java multithreading javafx