3 Replies Latest reply: Mar 4, 2013 5:25 PM by Bluewizard RSS

    JavaFx Application Thread - Platform.runLater

    Bluewizard
      Hi,

      We have an application that has a few background running threads that interact with our JavaFx GUI. All updates are done using the Platform.runLater pattern. We are running into an issue that when the background threads get cranked up they can send thousands of update requests. We then notice that the GUI gets very jerky and slows down even freezing for long chunks of time. I can sort of fix the problem by putting in Thread.sleep( 50 ) calls before performing the next Platform.runLater.

      Is this a know side effect of the Application Thread being over loaded? Is there a way to find out the current depth of the Application Thread?

      Thanks.
        • 1. Re: JavaFx Application Thread - Platform.runLater
          Richard Bair
          Yes, this is a well known problem (Swing has the same problem as does most every toolkit I know of), which I usually refer to as "swamping the event queue". What is happening is that lots of micro updates are being placed on the event queue and the toolkit has to process all these micro updates in between handling useful stuff like painting :-).

          The typical solution is to batch up the updates. You can look at the code for Task.java (http://hg.openjdk.java.net/openjfx/8/master/rt/file/16e4c07f8562/javafx-concurrent/src/javafx/concurrent/Task.java) to see how I did this for the Task. The basic theory is, when a change happens on the background thread, check to see if a previous change has already been added to the event queue and not yet processed. If not, then do the runLater as before. However if a previous job was fired off but not yet handled, either add your new chunk of data to the set to be handled next or replace the value, etc.

          For example in Task we have the problem where from a background thread you can call updateProgress as often as you wish. So what I do is hold a reference to a ProgressUpdate that contains the new min, max, and value. And then if you call updateProgress before the last updateProgress event was handled, then I will just update the ProgressUpdate with the new values.

          If instead you were computing a bunch of little nuggets of data that all needed to be passed along, then you could use a ConcurrentQueue rather than an AtomicReference to pass that data along.

          Richard
          • 2. Re: JavaFx Application Thread - Platform.runLater
            jsmith
            Is this a know side effect of the Application Thread being over loaded?
            Overloading the JavaFX event handler by posting rapidly to Platform.runLater is a commonly reported issue in these forums.

            There is a related issue tracker request:
            http://javafx-jira.kenai.com/browse/RT-21569 "Throttling platform.runLater calls (javadoc update)"

            You might want to look into Richard's throttling solution on this thread: "Re: GUi pause even with Platform.runLater"
            Re: GUi pause even with Platform.runLater
            Is there a way to find out the current depth of the Application Thread?
            To get that info via a public API, you would need to file a feature request against the runtime:
            http://javafx-jira.kenai.com/
            • 3. Re: JavaFx Application Thread - Platform.runLater
              Bluewizard
              Thank you - very helpful.