Tuesday, February 16, 2010

JavaFx: Threading

If you're thinking of writing server-style applications with JavaFx, threading appears to be a problem. The first hurdle is that JavaFx programs run on the AWT event dispatch thread — which makes sense for a GUI. Unfortunately, server applications often run in a “headless” environment, and there are some AWT classes that shouldn't require a graphical display yet still like to throw if they don't have one. Which means that, if some of those classes are buried in the JavaFx runtime, you won't be able to run server applications period.

Assuming that you get past the headless issue, it shouldn't be too difficult to create a background thread (either by creating a thread directory, or via javafx.async.JavaTaskBase) and start a Java server application such as Tomcat in that thread (I say “should” because I haven't tried this). That Java application could then invoke non-GUI JavaFx classes, perhaps one that implements javax.servlet.Servlet, as I described in the previous post.

However, I think there are dragons lurking here. The only reason that you'd want to implement a servlet via JavaFx is to exploit language features such as data binding. Looking at the generated bytecode, however, I haven't found any synchronization and I've seen a lot of static members. In a multi-threaded environment like an app-server, this seems to be an invitation for data corruption.

I'm also somewhat disappointed at the threading support for writing GUI apps. As I've written elsewhere, long-running operations should execute outside of the event dispatch thread. The javafx.async package provides two ways to run such code: the first is JavaTaskBase, which as its name indicates, is meant to run code written in Java (and said code is not allowed to invoke JavaFx classes). The second approach is via Task, which is not terribly well documented (“does not define how to specify the code to run”), and appears to be meant for internal use by API classes such as javafx.io.http.HttpRequest.

Speaking of javafx.io.http.HttpRequest (which is not found in the provided src.zip): I ran the example provided in its class documentation, with the addition of printing the current thread for each of the callbacks it defines. And discovered that the callbacks were not executing on the event dispatch thread, so shouldn't be allowed to update GUI components. As I said, there are some dragons here.

On the positive side, when I look at the provided source code, I note that Brian Goetz (author of Java Concurrency In Practice) is listed in the @author tag for many classes. I can only hope that this association is ongoing, and that he gives some thought to JavaFx concurrency in practice.

No comments: