绑定StringProperty时出现multithreading错误

我有一个关于multithreading和StringProperty绑定的问题。

我有一个类CacheManager ,它包含一个Thread ,它根据服务器上的更改更新我的缓存。 现在,我想通知文本和进度的百分比(这是JavaFX中的LabelProgressBar )。 我DoubleProperty使用公共静态DoublePropertyStringProperty ,它们在CacheManager类中定义。 我只是像这样绑定它:

 progressBar.progressProperty().bind(CacheManager.progress); someLabel.textProperty().bind(CacheManager.status); 

现在,在Updater线程中,我更新了这些Properties 。 使用DoubleProperty可以正常工作, ProgressBar可以很好地显示进度。 但是,使用状态(这是StringProperty的文本)更新Label会引发错误: java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-9 java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-9

现在,我的问题是: 为什么DoubleProperty工作得很好,而StringProperty会抛出错误? 他们考虑multithreading有什么区别?

任何关于重新设计的想法也欢迎,非常感谢任何帮助!

调用导致从FX应用程序线程以外的线程更改UI的代码是错误的, 无论它是否抛出exception 。 如果您违反此规则,FX工具包会尽最大努力抛出exception,但在某些情况下,对性能的影响太大而无法执行检查。 如果创建这些绑定,则必须在FX应用程序线程上执行对您绑定的属性的任何后续更改。 即,如果您在后台线程中运行,则必须使用以下代码更改属性:

 Platform.runLater(() -> CacheManager.progress.set(...)); 

 Platform.runLater(() -> CacheManager.status.set(...)); 

由于您可能不希望将服务代码绑定到JavaFX(通过Platform类),因此可以考虑使用侦听器而不是绑定,并从侦听器调度更新:

 CacheManager.progress.addListener((obs, oldValue, newValue) -> Platform.runLater(() -> progressBar.setProgress(newValue.doubleValue()))); CacheManager.status.addListener((obs, oldStatus, newStatus) -> Platform.runLater(() -> someLabel.setText(newStatus))); 

如果使用这些侦听器替换绑定,则可以自由更新任何线程上的属性。