I've put together a simple publish/subscribe pattern to allow multiple JavaFX classes to be dynamically instantiated and run. Each of these classes (a 'subscriber') is meant to visualize data coming from a model (in the model/view/controller sense) which has the role of 'publisher'. Data for visualization comes in the form of immutable objects, and is passed from the model (running in it's own thread) to a 'buffer' (also running in a separate thread) via a LinkedBlockingQueue. The Buffer then re-publishes all of the data from the model by putting it into LinkedBlockingQueues that are being emptied by threads responsible for running JavaFX visualizations.
So, the data path looks like this:
Model produces immutable objects ----(LinkedBlockingQueue)---> Buffer consumes objects and puts them on multiple queues ====(LinkedBlockingQueue) ===> Visualization thread consumes objects, does some pre-processing, and makes data available to a Timeline animation, which periodically updates the chart.
The entry point for the program extends Application, and its start() method builds all the JavaFX GUI components like so:
for (ModelVisualization viz : vizList) {
viz.buildGUI();
new Thread(viz).start();
}
The threads you see being started are the final consumers of the data in the description of the data-path above.
The problem: The visualizations show up and build properly, but nothing in any JavaFX window updates until the model thread goes to sleep. I can use System.err.println() statements to verify that the data from the model is moving through the various threads without deadlock, and I can see that the visualization threads are consuming everything properly. However, unless the model thread hits a Thread.sleep(100) or similar, the method associated with the Timeline never runs.
The model thread itself is started in the entry point constructor like so:
Thread simThread = new Thread(new Runnable() {
#Override
public void run() {
model.runSim();
}
});
simThread.setPriority(Thread.MIN_PRIORITY);
simThread.start();
...And only after that is the JavaFX stuff started up with:
launch();
This should, if I understand things correctly, have the model thread running independently of JavaFX. According to my system resource monitor, I have four whole unused cores (using a Core i7 on OSX) when this program is running, so it doesn't look like I'm starved for resources.
I do not know why JavaFX is paralyzed when my model thread is running. Sleeping my model thread is also something I'd like to avoid. Can anyone shed some light on what's going on, or how I might get JavaFX running properly?
Java FX is single threaded. You need to do Thread management in a special way for FX applications. Have a look here, and here.
Basically, you want to update your view, however, the view (thread) cannot synchronize with your other threads. Use the Platform tools in order to "play" with other threads.
Related
I have recently learnt that jMonkey operates on only a single thread which is its openGL render thread. However I'm not able to understand it completely. I can understand that it executes all update and initialize() calls on a single update loop but input should be independent of this update loop, otherwise it will become a polling mechanism.
What exactly happens when the jMonkey application starts. Three tasks that it needs to do is run a update loop, run initialize methods of app states once, do rendering and constantly cater to events? How does it manage all of this via a single thread?
What happens when I add a new app state in the initialize method of another app state?
In input handling input manager notifies the various listeners about events. How are nifty callback events say onClick() are handled on the same render loop?
Lastly in which order this listen- update-render loop runs and where we can find code related to it?
jME uses an approach that's very common in a lot of game engines (and also used in some other user interface libraries such as Swing).
Everything that the game engine does is done in one thread. This can be called the LWJGL thread but as jME can work with alternatives to LWJGL it's more generic to call it the Render Thread or just the jME Thread.
Everything is indeed done on the Render thread, and it does indeed use a polling mechanism. For example if you are holding down the "left" key then each frame the relevant control or app state will be called on the render thread and will move you left by an amount modified by tpf. Tpf is time-per-frame and is very important for keeping smooth movement and letting game systems run at the same speed independently of frame rate.
The only thing within jME3 that commonly uses a separate thread is the Physics Engine. That has a thread that it uses for doing the physics updates and then changes are pushed through to the Render thread using appropriate mechanisms. The system handles this for you though so it is not something you need to worry about.
The thread runs around a game loop. Each time around the loop it checks for things it needs to do (like enqueued tasks, initialize app states, render, etc. It calls update in each active Controller and control, etc). Once it has finished updating everything it then goes on to perform the render. All of this happens every single frame, but computers are so fast that it can still handle all of that and render the game at good frame rates.
That's an implementation detail that you shouldn't need to worry about except to know that it will definitely work. The adding actually gets queued up and handled in the next frame I think.
Everything is handled from the same loop. jME calls through to Nifty to allow Nifty to do its processing. As part of that processing Nifty detects the events and fires off the callback. This means that the callbacks are already coming in on the render thread so you can safely modify the scene graph. jME uses some specially written collections such as SafeArrayList to allow you to modify the scene graph at the same time as iterating over it.
Update, Render, Update, Render, etc. Events firing generally happens as part of the update process when an update is detected. To find the code start by looking in the Application class, you should be able to find the main game loop in there by tracing through from the start() call.
The jME3 Threading Tutorial covers a fair amount of this:
http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:multithreading
I have a question about the use of threads in a gui application. Say (as a simplistic example) i have a swing application with a series of images. I have two threads i want to run that fetch an image of a parent respectively. (So for a given number of students, get a mother image and a father image from each server endpoint). The returned image of the father and the mother is then appended on to the image on screen so i have a series of images with a mother, father, mother, father for multiple students.
How can i schedule this in a multithreaded environment? Each call to get a mother or father image has to be in parallel and not block the displaying of the images on screen. Does the image displayed on the screen refresh after each thread returns an image? How will this be structured?
Start with Concurrency in Swing.
The absolute simplest approach might be to use a SwingWorker that has a list of items it needs to look up and allow it to process the list.
The problem with this is it will only run each request one at the other, making it a little slower then other options. The benefit of this is that it provides easy functionality to re-sync with the Event Dispatching Thread so that you can notify the UI or make changes to it safely.
Another option might be to use Executors, in particular a Thread Pool implementation.
This allows you to submit a number of tasks that should be executed at some time in the future, but allows you to control the number of threads that the process can use at any one time.
The drawback is that you become responsible for syncing the changes back to the UI yourself when you want to update the UI, using SwingUtilities.invokeLater
Now. You "could" use both.
Basically you would need to setup some kind of "request" class that would allow you to pass the relevant information to, for example, the "mother" and "father" servers, the original image and possibly some kind of callback interface that would tell you when the final image had being rendered.
The requester would build some kind of Runnable or Callable which would wrap a SwingWorker.
When executed, this "request task" would start the SwingWorker, allowing it to fetch the images, merge them and publish the results, which would notify the callback interface. The "request task" would then simply wait until SwingWorker#get returns before exiting.
As an idea...
I have recently used Quartz scheduler for running some background processes (eg. report generation) that involves database access. Now, this background tasks runs in separate threads. However, the database access in done in a central point in my application, and something like
System.err.println("CURRENT THREAD: "+ Thread.currentThread().getName());
prints "main", before executing the actual query. Therefore, i am thinking that the database read is done by the UI thread ("main" thread). This is also confirmed by the fact that the UI loses (in part) his responsiveness. What i want to do, if possible, is to run every database access in a separate thread, so that a Cancel button can be implemented to a query request, if that will become necessary. So, i imagine having this workers:
UI thread: responsible for UI;
Database access thread: responsible for data retrieving from the db;
Scheduled background tasks: responsible for everything else (and using the DB access thread).
Can this be realized? Or, is there a better alternative to my approach?
P.S. I do not want to use at this point some existing frameworks, that address this issue (Hibernate, Spring, etc). I just need a home-brew, working solution.
Stack trace:
at com.mycompany.myproduct.core.db.SQL.executeQuery(SQL.java:260)
at com.mycompany.myproduct.core.db.Database.getAbstractDBObjects(Database.java:285)
at com.mycompany.myproduct.core.db.Database.getAbstractDBObjects(Database.java:305)
at com.mycompany.myproduct.core.util.job.DummyJobProcessor$1.run(DummyJobProcessor.java:61)
at org.eclipse.swt.widgets.RunnableLock.run(Unknown Source)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Unknown Source)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Unknown Source)
at org.eclipse.swt.widgets.Display.readAndDispatch(Unknown Source)
at com.mycompany.myproduct.core.ui.layers.AbstractView.open(AbstractView.java:915)
at com.mycompany.myproduct.mycompany.open(mycompany.java:196)
at com.mycompany.myproduct.mycompany.main(mycompany.java:365)
It seems like your db queries are run from the UI thread even though you say that a scheduled task runs the queries (?). To be sure, you can print out a stacktrace where you access the database:
new Exception().printStacktrace();
Over to your proposed solution: it seems like a decent design if your db queries are slow and otherwise would freeze your UI. You could implement an event system between your UI layer and the db layer, perhaps a simple queue based approach.
EDIT:
There are most likely examples to find how to implement a event based solution.
Disclaimer: I haven't done any real UI programming in many years.
The user clicks a button in the UI. The UI thread puts an event object (DataWantedEvent) on a queue (java.util.Queue), changes a label ("Waiting for data...") and then goes on and waits for other user interactions.
The db layer thread takes the event form the queue and queries the database. The result is posted back on another queue in a result object.
A UI thread (not the main thread probably) takes the result object from the result queue and updates the UI.
A queue for posting result objects back to the UI might not be needed. An update method could be invoked directly.
If the user clicks a cancel button, the update event/callback could be ignored or, if possible, the db query could be cancelled.
You can have a listener implementation that directly updates the UI. Something like a function callback, that gives an event to the UI thread.
That way , your UI thread can continue serving the input request, assuming you business logic does not require it to be a synchronous db request.
You could always do it asynchronously.
HTH.
It's about an application which is supposed to process (VAD, Loudness, Clipping) a lot of soundfiles (e.g. 100k). At this time, I create as many worker threads (callables) as I can put into memory, and then run all with a threadPool.invokeAll(), write results to file system, unload processed files and continue at step 1. Due to the fact it's an app with a GUI, i don't want to user to feel like the app "is not responding" while processing all soundfiles. (which it does at this time cause invokeAll is blocking). I'm not sure what is a "good" way to fix this. It shall not be possible for the user to do other things while processing, but I'd like to show a progress bar like "10 of 100000 soundfiles are done". So how do I get there? Do I have to create a "watcher thread", so that every worker hold a callback on it? I'm quite new to multi threading, and don't get the idea of such a mechanism.
If you need to know: I'm using SWT/JFace.
You could use an ExecutorCompletionService for this purpose; if you submit each of the Callable tasks in a loop, you can then call the take method of the completion service - receiving tasks one at a time as they finish. Every time you take a task, you can update your GUI.
As another option, you could implement your own ExecutorService that is also an Observable, allowing the publication of updates to subscribing Observers whenever a task is completed.
You should have a look at SwingWorker. It's a good class for doing lengthy operations whilst reporting back progress to the gui and maintaining a responsive gui.
Using a Swing Worker Thread provides some good information.
I have a little java app to effectively "tail" an arbitrary collection of files defined in an ini file. My "LogReader" class extends JFrame, and does the heavy lifting; reading the collection of file paths into a vector, and then iterating over the vector, reading each file and adding the last X lines of each to a text areas on the tabs of a JTabbedPane. The process of building the vector and iterating over the files is kicked off by clicking a JButton, via an ActionListener.
The reading of the files worked fine (and still does), but the process of reading 20-some files, some growing as large as 30MB, takes some time. To help pass that time, I decided to add a progress screen, which says "Now reading file #3 of 26: c:\logs\superduper1.log", and so on. So I created another class, "SplashScreen", also extending JFrame, and added a JLabel that would indicate the progress. The SplashScreen class has an update() method, which just does a setText() on the JLabel.
The ActionListener on the JButton calls RefreshLogs(), which looks something like:
vctFileStrings.clear();
tpMain.removeAll();
frmSplash.update("Loading Configuration"); //Update the label on the Splash Screen instance
BuildVectorOfLogs(strConfFile); //Read the collection of files into the vector
frmSplash.update("Reading Logs");
ReadLogs(); //read the files, updating the Splash Screen as we go
and then ReadLogs() iterates over the vector, reading the files and building the TabbedPane.
What I noticed, though, is that when RefreshLogs() is called from within the ActionListener, the Splash Screen doesn't update. However, if I add RefreshLogs() to the constructor of the first frame, the splash screen works as expected (updates progress on each file). After some experimenting and reading, I think that I need to create a worker thread that reads the files, while updating the splash screen in the event-dispatch queue.
My questions are:
- Is my thought correct? Is there some simple alternative to implementing threading that would allow me to update the splash screen from the method called by the ActionListener?
- If this would be best accomplished using threading, what scope of the activity would I need to thread? Would I need to put all of the file I/O activities into their own thread? Should I put the GUI activities (label updates) in their own thread, so they occur separately from the JButton click event?
I would say: yes, your thoughts on offloading the reading of large files to a separate thread are correct. You should never perform long tasks on the Event Dispatch Thread, since while that thread is busy, the GUI will be unresponsive, and you application will feel slow.
This sounds like good case for SwingWorker. This class allows you to perform slow requests (such as disk or network access) on a separate thread, with progress updates being fed back to the GUI with the EDT. SwingWorker looks after all complexities of switching between threads. All you have to do is implement your business logic in the appropriate places.
Sun has a tutorial on SwingWorker.
Yes, you should put your time intense reading into a separate thread. Now you do everything in the event-dispatching thread (EDT), which would update your GUI but is busy reading your data.
You can use SwingWorker for this. Have a look at Using a Swing Worker Thread which looks like what you need.
One suggestion for you, to figure out how to do this, and in case you are using NetBeans or have access to NetBeans, is to look at the default Java Desktop Application template. It creates a pre-wired desktop app with progress bar built into a status bar, that will automatically get updated when any "Action" code gets executed. It leverages the Action API which is also pre-wired to run in a background thread.
By looking at that auto-generated code you'll be able to properly and easily implement it in your own.