10

我有几个关于Platform.runLater. 我有一个 JavaFX 应用程序类。在这个类中,我运行一个线程(线程从网络套接字读取数据)。

现在,当我在线程内创建一个新Stage线程时,系统会抛出一个 execption(JavaFX 事件调度程序线程和我的 netork-read 线程不一样) - 我理解这种行为。

但另一方面是,我将网络阅读器中的文本附加到现有的TextArea或添加/删除 a 中的某些项目ListView<String>- 这不会引发异常 - 为什么?我认为 JavaFX 是单线程的(ui 库部分)。这是否与 Swing 中的相同:有时它可以工作,有时你只有垃圾(因为 EDT)?

我的问题:

  • JavaFX 事件调度程序线程何时抛出异常,何时不抛出异常?
  • 关于这个有什么好的文件吗
  • 是否有一种更简单(更短、更清洁)的方法来使用Platform.runLater方法run()?结合try catch(或multiple catch),看起来很奇怪

我知道Platform.runLater在线程中的使用不是很好(设计解决方案)

4

2 回答 2

19

亚历山大的回答抓住了关于您的问题的最重要的一点。

这个答案提供了一些补充信息。

JavaFX 事件调度程序线程何时抛出异常,何时不抛出异常?

JavaFX 系统并不总是检查对影响活动场景图的对象的访问是否正确地限制在 JavaFX 线程中。最终,确保这种线程安全是 JavaFX 应用程序程序员的责任,而不是 JavaFX 系统。在 JavaFX 中执行多线程编程时必须非常小心,否则应用程序行为可能会失败或变得不可预测。

关于这个有什么好的文件吗

试试 JavaFX 教程:JavaFX 中的并发

有没有一种更简单(更短、更简洁)的方法来使用 Platform.runLater 和 run() 方法?

Platform.runLater,就是这么简单。


作为旁白 。. .

任务与服务

考虑使用Worker的TaskService子类。这些是FutureTask的 JavaFX 包装器(又是Runnable)。Worker 提供了一个调用方法来在后台线程上运行逻辑。它们维护执行状态(通过向 JavaFX 线程发出线程安全回调通知以进行状态更改)并通过valuemessageexception属性返回调用结果。

Task利用和javadoc 示例中的设计模式Service来简化线程安全应用程序的创建,这些应用程序具有以下特性:

  • 为 UI 更新异步获取数据。
  • 任务进度的定期消息更新。
  • 构建尚未附加到显示场景的节点图。
  • 通过进度条等监控进度。

AWorker与 互补Platform.runLaterPlatform.runLater当您在 JavaFX 应用程序线程之外执行并且想要在 JavaFX 应用程序线程上运行一些逻辑时使用。当Worker您在 JavaFX 应用程序线程上运行并希望在新线程上产生一些逻辑或(尤其是)I/O 时使用 a,这样您就不会阻塞 JavaFX 应用程序线程。您永远不会想在 a 的方法中进行网络 I/O Platform.runLaterrun但通常希望在 aWorkercall方法中进行。

此外,TaskandService的使用与Platform.runLater. 例如,如果您有一个很长的运行Task时间,您希望定期或在缓冲区填充时将部分结果返回到 UI,那么Platform.runLater在任务的call方法中执行就是执行此操作的方法。

当您没有库提供的现有线程服务,而是创建自己的线程以在后台执行时,工作者很有用。如果您有一个现有的线程服务,那么您将需要使用Platform.runLater在 JavaFX 应用程序线程上执行逻辑。

请注意,即使您使用Worker. 您仍然必须注意不要违反标准 JavaFX 并发规则,例如从不更新活动场景图中的节点(包括不更新活动场景图中的节点绑定到的值 - 例如支持的可观察项目列表一个列表视图)。

于 2013-03-02T01:00:20.877 回答
13

“这不会引发异常 - 为什么?” 因为并非所有此类情况都被咳嗽......可能,出于性能考虑,它可能只是一个错过的功能。

如果您想从另一个线程访问这些 JFX 对象,则必须在 JFX 线程上完成与 JavaFX 对象的所有交互(包括创建) - 使用 runLater 或 runAndWait 方法。如果它现在不抛出异常,它可能会在未来开始抛出异常。与 JFX 对象的任何交互都可能导致后续的操作和事件,这些操作和事件将被某些线程检查器检查 - 您无法确定。

我不认为,这方面有任何好的文档——只是一个简单的规则——使用 runLater 或 runAndWait。

更短更简洁的方式 - 将使用 Lambda 在 JDK 8 中提供。

于 2013-03-01T15:07:23.010 回答