Javafx:javafx.concurent和Platform.runLater之间的区别? [英] Javafx: Difference between javafx.concurent and Platform.runLater?

查看:285
本文介绍了Javafx:javafx.concurent和Platform.runLater之间的区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我想知道javafx.concurent和Platform.runLater在多线程JavaFx编程中的区别是什么。 ,我们可以有多个实际的绘图线程或者它总是在一个线程上结束吗?



例如,我喜欢使用JavafX和swing同时,因为他们使用2不同的绘图线程。我会使用swing为重的东西(例如打开一个FileChooser)和使用JavaFX的核心视觉材料,例如播放一个无缝,循环的视频。然而,mac使这是不可能的,因为那个无头的异常错误,所以一切都在javafx上,这意味着很多停顿时,像做打开文件选择器。



如果我重写我的应用程序与javafx.concurrent,我可以基本上模仿那个2绘制线程的经验,我曾经对Swing + JavaFX?

解决方案

Platform.runLater



工人是对平台.runLater




  • 使用 Platform.runLater 当你执行JavaFX应用程序线程,并且你想在JavaFX应用程序Thread上运行一些逻辑。

  • 使用 Worker ,当您在JavaFX应用程序线程上运行并想要在一个新线程上产生一些逻辑或(特别是)I / O,以便不阻塞JavaFX应用程序线程。 >



你不会在 Platform.runLater 运行方法,但通常希望在 Worker call 方法。



任务和服务



请考虑使用任务服务子类 Worker 。这些是 FutureTask 的JavaFX封装容器(依次是 Runnable )。工作者提供调用方法以在背景线程。它们维护执行状态(通过线程安全的回调通知到JavaFX线程)用于状态更改),并通过返回调用结果, a href =http://docs.oracle.com/javafx/2/api/javafx/concurrent/Task.html#messageProperty>消息和异常属性。



利用任务服务 javadoc示例简化具有以下功能的线程安全应用程序的创建:




  • 异步获取用于UI更新的数据。

  • 定期更新任务进度信息。

  • 构建尚未附加到显示场景的节点图。

  • 通过进度条等监视进度。



同时使用Workers和Platform.runLater



此外,使用任务服务与使用 Platform.runLater 不兼容。例如,如果您有一个非常长的运行任务,您希望定期将部分结果返回到UI,或者作为缓冲区填充,然后执行在任务的调用方法中的Platform.runLater 是方法。



使用现有的线程系统



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



请小心编写多线程代码



请注意,您仍然需要知道自己正在做什么, Worker 。您还必须注意不要违反标准的JavaFX并发性规则,例如从不更新活动场景图上的节点(包括不更新活动场景图中的节点所绑定的值 - 例如项目支持ListView )。



回答您的部分添加问题


这意味着使用javafx.concurrent,我们可以有多个实际的绘图线程,


在JavaFX中只有一个渲染线程。您不能使用JavaFX并发来创建更多的渲染线程。你可以做一些事情,比如从JavaFX线程创建节点,或者将像素设置为一个屏幕外的WriteableImage或Canvas使用许多线程,但是最终每个渲染操作都通过一个由你无法控制的JavaFX系统管理的单个线程。


如果我重写我的应用程序使用javafx.concurrent,我可以基本上模仿2绘制线程体验,就像我曾经使用Swing + JavaFX?


否。即使你可以,我不认为这是可取的。有了这样的模型,太容易创建微妙,难以调试线程处理相关的错误。



有关为什么有两个或更多绘制线程的相关文章,请参阅相关文章。可能不合适:





Java 8添加了一个实验命令行开关, JavaFX应用程序线程和Swing事件分派线程。这样做的主要原因是它简化了编程模型。


一切都落在javafx上,这意味着在执行诸如打开文件选择器。


也许你的代码效率低下(如在UI线程上执行I / O),导致暂停。


重的东西(例如打开FileChooser)



$ b b

打开和渲染FileChooser不重。 JavaFX可以轻松处理这样的操作,而不会降低性能。什么是耗时的是与I / O相关的东西,例如,递归地走一个大文件树以获得文件属性。在这种情况下可以做的是在 Worker 中生成一个I / O运行线程,并通过 Platform.runLater 。这样的方案将很好地工作。瓶颈不是绘图,所以拥有另一个绘图线程没有提供优势。瓶颈是缓慢的I / O系统,并且通过为I / O使用单独的线程来缓解这种瓶颈,使得主UI线程不受影响,并且当I / O发生时用户不会遇到UI冻结。 p>

I'm curious as to what exactly the difference is between javafx.concurent and Platform.runLater for multithreaded JavaFx programming.

Does it mean that with javafx.concurrent, we can have multiple actual drawing threads or does it all end up on one thread anyway?

E.g One thing I enjoyed was using JavafX and swing concurrently as they both used 2 different drawing threads. I would use swing for the heavy stuff (e.g. opening a FileChooser) and use JavaFX for the core visual stuff e.g playing a seamless, looping video. However, the mac makes this impossible because of that headless exception error so everything fell on javafx and that meant a lot of pauses when doing things like opening filechoosers.

If I rewrite my app With javafx.concurrent, could I essentially mimic that 2 draw thread experience as I once did with Swing + JavaFX?

解决方案

Platform.runLater

A Worker is complementary to Platform.runLater.

  • Use Platform.runLater when you are executing off of the JavaFX Application Thread and you want to run some logic on the JavaFX application Thread.
  • Use a Worker when you are running on the JavaFX Application Thread and want to spawn some logic or (especially) I/O on a new thread so that you don't block the JavaFX Application Thread.

You would never want to do network I/O inside a Platform.runLater's run method, but would often want to do it in a Worker's call method.

Task and Service

Consider using the Task or Service subclasses of Worker. These are JavaFX wrappers for FutureTask (which is in turn a Runnable). Workers provide a call method to run logic on a background thread. They maintain execution status (with thread safe callback notification to the JavaFX thread for state changes) and return results of the call via value, message and exception properties.

Take advantage of the design patterns in the Task and Service javadoc examples to simplify creation of thread-safe applications with features such as:

  • Asynchronous fetching of data for UI update.
  • Periodic message updates for task progress.
  • Constructing Node graphs which are not yet attached to a displayed scene.
  • Monitoring progress via progress bars, etc.

Using Workers and Platform.runLater together

Also, usage of Task and Service is not incompatible with use of Platform.runLater. For instance, if you have a very long running Task from which you want to return partial results to the UI periodically or as a buffer fills, then executing Platform.runLater in the task's call method is the way to do that.

Working with existing threading systems

Workers are useful when you don't have an existing threaded service provided by a library, but are instead creating your own threads to execute in the background. If you have an existing threaded service, then you will need to use Platform.runLater to perform logic on the JavaFX application thread.

Be careful writing multi-threaded code

Note that you still need to know what you are doing, even if you use a Worker. You must still take care that you don't violate standard JavaFX concurrency rules, such as never updating Nodes on the active scene graph (including not updating values that Nodes in the active scene graph are bound to - such as the observable list of items backing a ListView).

Answering some of your addition questions

Does it mean that with javafx.concurrent, we can have multiple actual drawing threads or does it all end up on one thread anyway?

There is only one render thread in JavaFX. You cannot make more render threads using JavaFX concurrent. You can do things like create nodes off the JavaFX thread or set pixels to an off screen WriteableImage or Canvas using many threads, but eventually every render operation passes through a single thread managed by the JavaFX system over which you have no control.

If I rewrite my app With javafx.concurrent, could I essentially mimic that 2 draw thread experience as I once did with Swing + JavaFX?

No. Even if you could, I don't think it would be advisable. With such a model it is far too easy to create subtle, hard to debug thread processing related errors. And the gain you might see from such a setup may be less than you may wish for or expect.

See related articles on why having 2 or more "draw threads" is likely inadvisable:

Java 8 is adding an experimental command line switch to use the same thread for the JavaFX application thread and the Swing event dispatch thread. The main reason for this is that it simplifies the programming model.

everything fell on javafx and that meant a lot of pauses when doing things like opening filechoosers.

Perhaps there were inefficiencies in your code (such as performing I/O on the UI thread) which caused the pauses.

the heavy stuff (e.g. opening a FileChooser)

Opening and rendering a FileChooser is not heavy. JavaFX can easily handle such an operation without a performance degradation. What can be time consuming is stuff related to I/O, for example walking a large file tree recursively to get file attributes. What you can do in such cases is spawn a thread for the I/O run it in a Worker and periodically feed back partial results to the UI thread via Platform.runLater. Such a scheme will work well. The bottleneck is not the drawing, so having another drawing thread provides no advantage. The bottleneck is the slow I/O system and this bottleneck is mitagated by the using a separate thread for I/O so that the main UI thread is not impacted and the user does not experience UI freezes while I/O is occurring.

这篇关于Javafx:javafx.concurent和Platform.runLater之间的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆