【发布时间】:2011-03-07 11:03:12
【问题描述】:
我编写了一个简单的 Javafx 应用程序,它启动了一个新线程,并且在 Netbeans 上运行良好。 但我在编译过程中收到以下警告:
explicit use of threads is not supported
这是否意味着它现在可能适用于所有可能的设备,例如手机或浏览器?
【问题讨论】:
标签: java multithreading javafx
我编写了一个简单的 Javafx 应用程序,它启动了一个新线程,并且在 Netbeans 上运行良好。 但我在编译过程中收到以下警告:
explicit use of threads is not supported
这是否意味着它现在可能适用于所有可能的设备,例如手机或浏览器?
【问题讨论】:
标签: java multithreading javafx
JavaFX 本身必须在 JavaFX 主线程上运行,因此目前不支持直接从 JavaFX 启动线程。但是,您可以创建一个生成线程的 Java 类。因此,您的 JavaFX 类调用 Java 类,然后启动一个线程。
从 Java 线程回调 JavaFX,您需要在 JavaFX 主线程上。如何做到这一点的一个例子是:
import com.sun.javafx.runtime.Entry;
Entry.deferAction( new Runnable() {
@Override
public void run() {
fxListener.onMessage(copy);
}
} );
您不应直接从 Java 操作 JavaFX 对象。如果您使用 Java 执行此操作,则需要使用 javafx.reflect 类。
【讨论】:
我不得不推荐 JFXtras (http://jfxtras.org/) XWorker 类。它本质上是您提到的问题的解决方法,它允许您在后台线程中使用 JavaFX 代码。它适用于大多数任务,但也有点危险,因为您可以使用它轻松创建非线程安全的代码。
基本用法:
var currentImage:Image;
var worker = XWorker {
inBackground: function() {
return Image {url: currentFile.toURL().toString(), height: imageHeight};
}
onDone: function(result) {
currentImage = result as Image;
}
}
在 inBackground 中所做的一切都是在后台 Swing 线程中完成的。该线程可以返回一个结果,该结果将传递给 onDone。 onDone 在 JavaFX 事件调度线程(所有其他 JavaFX 代码运行的主线程)中执行,因此您可以恢复正常使用。把它想象成前景。在大多数情况下,您不想访问在“前台”中也可以同时访问的任何 inBackground 内容。只要您在线程之间共享的对象是线程安全的,您就可以对此规则进行例外处理。在大多数情况下,JavaFX 代码不能是线程安全的,但您可以使用 Java 线程安全对象(例如 JPA EntityManager 工厂)或容器,例如 BlockingQueue。后者对于制作生产者/消费者模型可能很有用。
另外,如果您有一个长时间运行的任务并且想要定期将更新发送到“前台”,您可以使用发布/处理。这是一个例子:
var worker = XWorker {
inBackground: function() {
while (true) {
// Do something
publish(someStuff);
}
}
process: function(someStuff: SomeStuff[]):Void {
// Do something with some stuff. You are now in
// "the foreground", so you can freely access
// JavaFX objects.
}
onDone: function(result) {
currentImage = result as Image;
}
}
这对于从后台线程发送日志消息以显示在某种 UI 中非常有用。
【讨论】: