Read up the threading system and Pulse section of the JavaFX Glass Windowing Toolkit:
https://docs.oracle.com/javase/8/javafx/get-started-tutorial/jfx-architecture.htm#A1107438
Also read the Application Lifecycle:
https://docs.oracle.com/javase/8/javafx/api/javafx/application/Application.html
Basically, in a simplified manner, the way it works is this.
The application is launched on the main thread like any other
Java program.
The main method is invoked in which an Application.launch() method is called.
The Application launch implementation will run the init() method of the application on the main thread.
The launch implementation will create the JavaFX application and run the application start method, then suspend execution of the main thread until the last window of the application is closed or Platform.exit() is called.
GUIs are event driven (for example user types on a key or clicks on a mouse to generate an event). When an event occurs it goes into a queue (I think) to be processed on the next pulse.
The JavaFX runtime makes use of an in-built timer. Usually this is implemented in native code for Windows or OS X and is set to generate a pulse event sixty times a second. So rather than a busy wait the signal to wake up the thread ends up being a interrupt based upon a hardware timer.
When the timer generates an event the JavaFX thread is woken up to see if there is any work to do (animation frames to execute, events from the event queue to handle), and if so it handles them, then generates css and layout passes and re-renders the scene. Then the JavaFX thread is suspended until the next pulse occurs.
Rules are a bit different if you use a JFXPanel embedded in a Swing application, but that is not the norm, so I won't go through that scenario here.
So the thread isn't working constantly, most of the time it is suspended and awaiting an event to wake it back up again. For this reason if you display a scene and the user is not interacting with the scene and no animations are running, then the thread is just suspended and not taking up any CPU cycles at all.
The guts of the implementation (for Windows) is in:
http://hg.openjdk.java.net/openjfx/9-dev/rt/file/eec7ea4e8513/modules/javafx.graphics/src/main/native-glass/win/GlassApplication.cpp
http://hg.openjdk.java.net/openjfx/9-dev/rt/file/eec7ea4e8513/modules/javafx.graphics/src/main/native-glass/win/Timer.cpp
http://hg.openjdk.java.net/openjfx/9-dev/rt/file/eec7ea4e8513/modules/javafx.graphics/src/main/native-glass/win/Timer.h#l67
As you might see, it is just leveraging underlying Windows OS systems for listening to events and translating them to JavaFX as well as a native Windows Timer to generate the timed pulses according to the desired frame rate (default sixty times per second). In the end, the timer Windows timer function used is timeSetEvent:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd757634(v=vs.85).aspx
Because the overall processing is generic across platforms most of the implementation is in Java, with interactions with the native windowing system only where necessary. The code relevant to the high level processing I outlined above that is generic across platforms can be found in the Quantum toolkit:
http://hg.openjdk.java.net/openjfx/9-dev/rt/file/eec7ea4e8513/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/QuantumToolkit.java#l301
You can see how the scene reacts to each pulse (applies CSS, runs a layout pass, etc) here:
http://hg.openjdk.java.net/openjfx/9-dev/rt/file/eec7ea4e8513/modules/javafx.graphics/src/main/java/javafx/scene/Scene.java#l2479