I am new to multithreading, Java and JavaFx. I am building an application with JavaFX UI which updates a graph continously based on live data. Here is the current design,
1. When a JavaFx button is pressed, I invoke a thread which sets up the framework to send requests and get responses
startButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
stopButton.setDisable(false);
if(!startButton.isDisable()){
runSequence = new Thread(new Runnable(){
#Override
public void run() {
SynchThreads sharedObject = new SynchThreads();
new Bridge(sharedObject);
startSequence = new Sequence(sharedObject);
startSequence.performCalls();
}
});
runSequence.start();
}
startButton.setDisable(true);
}
});
2. runSequence thread which is invoked as above invokes another thread "callbackThread" that constantly receives data. This data which is received is passed to runSequence thread for further processing
BusinessLogic businessLogic = new BusinessLogic();
executor.submit(pduApiDllCallBackThread);//This collects the data in background
//Here we are back on runSequence thread that works on the collected data.
while(true){
response = sharedObject.take();
businessLogic.primeData(response);
}
3. The BusinessLogic class after working on this data notifies the user interface with an event ID and data that should be shown on the graph.
UI.notifyListeners(0, graphCoords);//here event ID is 0 and graphCoords is a HashMap
4. In the user interface everytime I get the notification I update the LineChart by using Platform.runLater. This notification occurs every 4 millisecs. So, I end up doing a lot of Platform.runLater calls
public void notifyListeners(int eventType, Map<Integer, Float> graphCoords) {
Platform.runLater(new Runnable(){
#Override
public void run() {
//Old series is cleared. Showing dummy data being updated
series.getData().clear();
series.getData().add(new XYChart.Data("1", Math.random()+1));
series.getData().add(new XYChart.Data("3", Math.random()+5));
series.getData().add(new XYChart.Data("4", Math.random()-25));
series.getData().add(new XYChart.Data("2", Math.random()-10));
series.getData().add(new XYChart.Data("-1", xxx));
}
});
}
Please provide your expert tips if this is ok to do this or if there is a better way to handle this in UI.I do not have more control over the layer below UI which notifies the UI. As the notification occurs every 4ms I wanted to know if there is a better approach
Any help is appreciated. Please help. Thanks !
You might swamp the JavaFX event queue by executing Platform.runLater so often, so you might want to batch the responses up (say in groups of ten), then make a single runlater call for each batch.
There is a specific codereview site on stackoverflow.
Make sure you have animation turned off on the chart so it doesn't try to do too much with each update.
Your solution does seem a bit complicated, but perhaps it's warranted for your situation, I don't know.
I don't know how you are handling your concurrency, but take a look at java.util.concurrent and the concurrency tutorial if you haven't already. Also checkout Concurrency in JavaFX if you have not already. Sometimes the higher level java.util.concurrent framework is more expressive, less error prone, easier to work with and easier to reason about than the lower level object monitor wait/notify methods.
You may want to mark some of the threads you are using as daemon threads. You may also want to add some logic to handle interruption of threads or cancellation of processes, similar to the examples in the JavaFX Task documentation.
If you are new to Java, multithreading and JavaFX, starting off with a multithreaded, networked JavaFX app is jumping off the deep end.
Often, concurrent work is offloaded from the JavaFX application thread to worker threads using the Task/Service framework.
Related
I have an AnimationTimer, that I use as an infinite loop like this:
animator = new AnimationTimer(){
#Override
public void handle(long now) {
// Update
Game.simulationStep();
// Render
Game.render();
}
}
};
animator.start();
The handle function is called 60 times a second, updates a small Game and renders some views in a scenegraph.
What I´m asking myself is, if when I have Events like a button click, will the code of the event be executed after a loop iteration is done?
Or is it multithreaded?
The thing is, I have a List of GameObjects which can be manipulated by the event (removing GameObjects by button click) but also by the logic in simulationStep.
It could be problematic, if the event removes GameObjects from that List, while simulationStep() is doing something with the Objects in the List.
The answer depends not on the code you provide but on your other code.
If the code is responding to events originating in the JavaFX framework (like a button press), then you don't need to worry, because those events are also on the JavaFX thread, the same as the animation timer.
You only need to worry if the event originates on a different thread outside of JavaFX. For example, an incoming chat message from a network chat client, or an AI loop that you are running on your own thread.
Also, you shouldn't use property listeners and bindings that might change values on another thread. For example, don't modify from another thread an observable list that is used to back a list view. The internal implementation of the observer and binding features assumes that the properties and listeners are all used on a single thread. Again, that is only something to worry about if your code is actually multi-threaded.
If you do really have multi-threaded code with events originating from other threads, use JavaFX concurrency, e.g. Task and/or Platform.runLater. Possibly in conjunction with a queue as in Seph's answer as demonstrated (somewhat), by this multi-threaded JavaFX logging framework using a queue. However, usually a separate queue is not required, because Platform.runLater will add runnables to a built-in queue that JavaFX maintains for stuff to be run on the JavaFX thread later.
For your specific concern:
I have a List of GameObjects which can be manipulated by the event (removing GameObjects by button click) but also by the logic in simulationStep. It could be problematic, if the event removes GameObjects from that List, while simulationStep() is doing something with the Objects in the List.
No. It will not be problematic. Everything is running on a single thread, the GameObjects cannot be removed by button click while simulationStep() is running, because the click handler and the simulationStep cannot be running at the same time.
A good summary of different options for executing periodic events and when and when not to involve multiple threads, plus how to handle them if they are used, is in Slaw's answer to:
JavaFX periodic background task
I advise reading the JavaFX architecture overview sections on the Glass Windowing Toolkit, Threads, and Pulse (twice). The document explains how the JavaFX system works with respect to threading, event processing, and pulse handling (the AnimationTimer handle method is triggered by a pulse).
AnimationTimer is not multithreaded and the handle() method runs on the JavaFX application thread, so I guess if you put an infinite loop or a blocking call inside handle(), it freezes the application. Answering your question, unless you have some behaviour that executes on other threads, it'll work fine.
Here's a related thread: Is AnimationTimer running in its own thread?
You can add the events to a queue and process that queue first in your animation timer. This should avoid anytime of concurrency or race condition issues you may be concerned about without hurting anything if they do not actually exist.
animator = new AnimationTimer(){
#Override
public void handle(long now) {
//Process
Game.processEvents();
// Update
Game.simulationStep();
// Render
Game.render();
}
}
};
animator.start();
I am trying to write a multi-thread program with Swing. Essentially how the program works is that when it runs it will have a robot(represented by a circle in screenshot) that is wondering around in a field. This robot should be controlled by a thread of it's own. The program has a button "Launch Robot" that will create another robot on the field(upto a max of say 10). Right now I have the basics of the program, but it all runs under one thread. I can launch as many robots as I want but they all run under a single thread. But I want that whenever I click "launch Robot" an independent thread be created and control that robot. This is how the program looks right now:
The UML diagram for the program is as following:
Since its a bit long I won't post the whole program. But the method that starts and updates the robots(currently controlling only one robot on the field) is as follows:
public void gameStart(){
Thread gameThread = new Thread(){
public void run(){
while(true){
//execute one time step for the game
gameUpdate();
//refresh screen
repaint();
//give other threads time
try{
Thread.sleep(1000/UPDATE_RATE);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
};
gameThread.start();
}
My question is how can I achieve multi-threading for such a scenario? I know the basics of SwingWorker, but since I haven't done any multi-threading, I have no idea on how to make several threads work and be updated by one thread(update position of robots that are controlled by threads).
EDIT: Just to make my point, this is a project that I am working on. It's not about if multi-threading makes sense in this scenario or not.
Create a RobotModel that contains a Collection<Robot> and defines their interaction. Iterate the model in the doInBackground() implementation of a SwingWorker. Invoke publish() as meaningful events arise, and process() updates to the RobotWorld view by querying the model. As discussed here, there should be no drawing in the model and no interaction logic in the view. A single worker should suffice for a moderately complex model, but you can synchronize multiple workers as shown here.
A good option to achieve this is to use ScheduledThreadPoolExecutor.
Instantiate the thread pool via:
ScheduledThreadPoolExecutor threadsPool = new ScheduledThreadPoolExecutor(size);
To create a new Robot Thread, use:
threadsPool.submit(new Runnable() {
#Override
public void run() {
launchRobot();
}
});
This way, each invocation will instantiate a new Thread.
You can set the limit of the total number of allowed Thread via the "size" argument.
You can also pass a result after each thread completes using:
public <T> Future<T> submit(Runnable task, T result)
If you want less detail, you could let Java do the work for you with the following convenience API:
Executors.newCachedThreadPool() (unbounded thread pool, with automatic thread reclamation) or:
Executors.newFixedThreadPool(int) (fixed size thread pool)
Remember us, Executor. Remember what was done here today. And may Adun watch over you
This robot should be controlled by a thread of it's own.
Why?
IMO, the most important way to describe any thread is to say what it waits for. In an internet server, an accept thread waits for incoming connections from new clients, and a client thread waits for additional commands from a single client. In a program that performs massive parallel computations, a worker thread waits for tasks to be performed. In a GUI program, the event dispatch thread waits for keyboard and mouse events. Etc., etc.
What will your robot thread wait for?
If it waits for time to pass (i.e., if it calls Thread.sleep()), then your GUI framework probably already has a timer thread that does that, and you might want to consider using it. (In Swing, you would use the javax.swing.Timer class to submit new timed tasks.)
I have a javaFX application which visualizes compuational geometry algorithms. The execution of an algorithm happens in another thread, lets call it mainComputingThread.
An algorithm can update the UI at any time by adding/removing/modifying shapes.
so the code will look like:
//do some computaions (1)
updateUI();
//do some more calculations (2)
What I want know is in the updateUI method to update the UI immediately and prevent the calling thread from running further (marked as (2)) until the UI update is done.
I thought about boolean guards. So the code could would look like:
updateUI(){
boolean guard = false;
Platform.runLater(new Runnable()
{
run(){
//do the actual update
guard = true;
}
});
while(guard==false);
}
I hope you get an idea of what I mean. I'm really curious if there's a better solution for this problem...
Simple approach: block background thread until update is complete:
You need to update the UI on the FX Application Thread. Typically you do this by passing a plain Runnable to Platform.runLater(...).
If you want to wait for that ui update to complete before proceeding, instead create a FutureTask and pass it to Platform.runLater(...). Then you can call get() on the FutureTask, which will block until the task is complete:
private void updateUI() throws InterruptedException {
// actual work to update UI:
FutureTask<Void> updateUITask = new FutureTask(() -> {
// code to update UI...
}, /* return value from task: */ null);
// submit for execution on FX Application Thread:
Platform.runLater(updateUITask);
// block until work complete:
updateUITask.get();
}
This lets the FutureTask handle all the tricky work of waiting and notifying: it is always better to use a higher-level API for this kind of work when you can.
If you like, you can refactor this into a utility method, similarly to Dainesch's answer:
public class FXUtils {
public static void runAndWait(Runnable run) throws InterruptedException {
FutureTask<Void> task = new FutureTask<>(run, null);
Platform.runLater(task);
task.get();
}
}
Alternative approach: ensure that no more than one update is consumed during any frame rendering, blocking the background thread if an update is pending
Here is a somewhat different approach. Create a BlockingQueue with a capacity of 1 to hold the Runnables that update the UI. From your background thread, submit the Runnables to the blocking queue: since the blocking queue can hold at most one element, this will block if one is already pending.
To actually execute the updates in the queue (and remove them, so more can be added), use an AnimationTimer. This looks like:
private final BlockingQueue<Runnable> updateQueue = new ArrayBlockingQueue<>(1);
background thread code:
// do some computations...
// this will block while there are other updates pending:
updateQueue.put(() -> {
// code to update UI
// note this does not need to be explicitly executed on the FX application
// thread (no Platform.runLater()). The animation timer will take care of that
});
// do some more computations
Create the timer to consume the updates:
AnimationTimer updateTimer = new AnimationTimer() {
#Override
public void handle(long timestamp) {
Runnable update = updateQueue.poll();
if (update != null) {
// note we are already on the FX Application Thread:
update.run();
}
}
};
updateTimer.start();
This basically ensures that no more than one update is ever scheduled at any time, with the background thread blocking until any pending updates are consumed. The animation timer checks (without blocking) for pending updates on each frame rendering, ensuring that every update is executed. The nice thing about this approach is that you can increase the size of the blocking queue, effectively keeping a buffer of pending updates, while still ensuring no more than one update is consumed during any single frame rendering. This might be useful if there are occasional computations that take longer than others; it gives these computations a chance to be calculated while others are waiting to be executed.
Hard question to answer without having the reason why you want to stop processing before the UI update is done. (Note: the runLater method executes the UI updates in the order received) Is it to prevent spamming to many Runnables to the JavaFX thread? Other reasons?
Your basic idea however works with the use of a CountDownLatch so that the processing thread waits to acquire a permit. If you choose that approach use something like this:
public class MyFXUtils {
public static runAndWait(final Runnable run) {
final CountDownLatch doneLatch = new CountDownLatch(1);
Platform.runLater(new Runnable() {
public void run() {
try {
run.run();
} finally {
doneLatch.countDown();
}
}
});
doneLatch.await();
}
}
EDIT: replaced Semaphore by CountDownLatch
EDIT:
So, the quickest way I always do it in prototypes is as following, transform:
//do some computaions (1)
updateUI();
//do some more calculations (2)
into
ExecutorService executor = Executors.newFixedThreadPool(1);
class JobStep implements Runnable {
public void run() {
doSomeComputations();
Platform.runLater(() -> {
updateUI();
executor.submit(new JobStep());
});
}
executor.submit(new JobStep());
OLD PART
Not an answer, but a suggestion how to attack the problem.
From my experience, the complete solution would be much more elaborate. I would separate the JavaFX shape instances from the shapes, which your algorithm does process. I would do it by means of using different class types and synchronize between the two.
The graphical algorithms have the tendency to be a lot quicker than the ones that are visualizing it. If the algorithm runs on small data set, then the rendering most often tend to slow down it significantly. It can easily be seen by running the same algorithm with and without visualization.
If the data set is bigger than the most trivial ones, then drawing of a single frame can easily take more than one second. Interactive visualizations are expected to respond in "real time", preferably many times per second.
The data visualization facilities have many means to tackle the problem. The best candidates always include:
Simplifying visualization. Drawing simpler shapes instead of complex, like removing the rounding from boxes. The LOD (level of detail) also applies to this point: during interactive scroll the visualized elements might be replaced by bounding box counterparts.
Selective hiding. Drawing only a part of the whole data set.
Parallelizing and hardware acceleration. The GPU's natively provide many means to handle complex visualizations. Typically the low level programming APIs (OpenGL, shader programs) allow much better throughput than every high level wrapping API, including JavaFX
Most often, the end solutions incorporate not only above points, but also others, including domain specific optimizations.
The visualization facilities always come with a lot of restrictions, like the most common one: have to be updated in the dedicated thread (thread confinement approach). They also come with visualization specific data structures.
From the data processing algorithm stage, one of the most common requirements is that it cannot be blocked or delayed by visualization. The algorithms are also written in a style, which doesn't translate to well for the means of visualization: imperative loops over data structures instead of updating observable drawable objects. There is a good reason to it though: the algorithms are expected to be optimized for performance or memory consumption.
One architectural approach to the problem might be as following:
The data processing stage produces snapshots at predefined points. The adding, modifying and remove operations are all published as this packet. It can be a just a copy of data structure that is being processed or it can be in the form of the coalesced events.
The data processing and data visualization run on different threads. They communicate only by means of publishing snapshots, never by blocking each other directly.
The snapshots shouldn't be restricted to particular frame rate. There should be means to batch updates before drawing or drawing same batch multiple times if the data processing stage stalls.
I strongly recommend reactive approach to the problem. The RxJava provides nice example for the "suggestion box" feature. It's very good at correctly handling requirements like "Every key update do a long running process on different thread and discard the last one, if any was running. Or maybe, don't do it on every key update, but wait 50ms for the user to make up his mind before he ends typing".
I'm student and I'm working on project with few of my friends. My task is to make something like class library. Classes in this library should provide API for my friend who must make GUI part of application. GUI could be made by any toolkit (Swing, JavaFX, SWT, AWT, all should work, in fact, it should work even if there is no GUI). I need to make class that waits for data to arrive from network. I don't know when data will arrive, and UI must be responsive during waiting, so I put that in different thread. Now problem is how to make GUI respond when data arrive. Well, I tought that this is asynchronous event and GUI should register event handlers, and I should call that methods when event happens. I proposed this solution:
interface DataArrivedListener{
void dataArrived(String data);
}
class Waiter{
private DataArrivedListener dal;
public void setDataArrivedListener(DataArrivedListener dal){
this.dal = dal;
}
void someMethodThatWaitsForData(){
// some code goes here
data = bufRdr.readLine();
//now goes important line:
dal.dataArrived(data);
// other code goes here
}
}
My question is:
Should I replace "important" line with something like this:
java.awt.EventQueue.invokeLater(new Runnable(){
#Override
public void run(){
dal.dataArrived(data);
}
});
Or something like:
javafx.Platform.runLater(new Runnable(){
#Override
public void run(){
dal.dataArrived(data);
}
});
Or maybe I should do something completely different?
Problem is that I'm not sure which of this will work for any type of UI. If it's GUI, dataArrived() could potentialy make changes to GUI and no matter what type of GUI it is, this changes should be drawn on screen properly. I also think that it is better if I do "invoke this code later" so that my someMethodThatWaitsForData() method could trigger event and continue on with it's on work.
I appreciate your help.
Here's an Event Listener article I wrote a while back. The article explains how you write your own event listeners.
You're correct in that you want to write your own event listeners if you want your library to work with any GUI.
I'm most familiar with Swing, so yes, you'll have GUI code that looks like this:
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent event){
dal.buttonPressed(data);
}
});
If you want it to be completely agnostic to what GUI is being used the only real solution is to let the receiver handle it in dataArrived. Since every toolkit has its own implementation all you can really do to make it work with any toolkit is to disregard it. Otherwise what you will actually end up with is a list of "supported toolkits" and a case for each one.
If you just want dataArrived to be executed away from someMethodThatWaitsForData then you could make your own dispatch thread or make a new thread each time.
If you want to be truly independent of any front-end system, I would recommend creating two threads. The first is your Waiter, which will just listen for events and put them into a Queue of some sort (see the "All Known Implementing Classes" section). The second will invoke the data listener or listeners whenever the queue is not empty.
The concept of invoking a Runnable in the background is kind of deprecated since the invention of the concurrent package. The main reason that this was done in earlier days, is that the GUI code needs to be executed in a different thread, to guarantee that it stays responsive, even if the main thread is busy doing some calculations, but actual multi-threading was still in its very early days. The resulting invokeLater concept works, but comes with a strong creation overhead. This is especially annoying if you frequently have to do minor things, but each time you need to create an entire new Runnable, just to get that event into the Swing thread.
A more modern approach should use a thread-safe list, like a LinkedBlockingQueue. In this case any thread can just throw the event into the queue, and other listener/GUI-Event-handlers can take them out asynchronously, without the need of synchronization or background Runnables.
Example:
You initialize a new Button that does some heavy calculation once it is pressed.
In the GUI thread the following method is called once the button is clicked:
void onClick() {
executor.submit(this.onClickAction);
}
Where executor is an ExecutorService and the onClickAction a Runnable. As the onClickAction is a Runnable that was submitted once during Button creation, no new memory is accessed here. Let's see what this Runnable actually does:
void run() {
final MyData data = doSomeHeavyCalculation();
dispatcher.dispatch(myListeners, data);
}
The dispatcher is internally using the LinkedBlockingQueue as mentioned above (the Executor uses one internally as well btw), where myListeners is a fixed (concurrent) List of listeners and data the Object to dispatch. On the LinkedBlockingQueue several threads are waiting using the take() method. Now one is woken up as of the new event and does the following:
while (true) {
nextEvent = eventQueue.take();
for (EventTarget target : nextEvent.listeners) {
target.update(nextEvent.data);
}
}
The general idea behind all this, is that for once you utilize all cores for your code, and in addition you keep the amount of objects generated as low as possible (some more optimizations are possible, this is just demo code). Especially you do not need to instantiate new Runnables from scratch for frequent events, which comes with a certain overhead. The drawback is that the code using this kind of GUI model needs to deal with the fact that multi-threading is happening all the time. This is not difficult using the tools Java gives to you, but it is an entire different way of designing your code in the first place.
I have build a desktop application that connected to database, the function is add-delete-modify. I make it separate to 3 JInternalFrame.
The problem now is, when I execute bulk update to update >500 orders, my application will hang but it is processing the request. Then I will run this application again, so now I have 2 windows opened with same application. After the 1st application is done for the job, I can use my previous application again.
Now my question is, how to implement thread to my app so that I can run as many function in same window application?
Long-running tasks (like your bulk update) must not be done in the event dispatch thread (the thread where all the GUI operations are made), else, as you observed, the GUI freezes.
Use SwingWorker to execute your long-running tasks in a background thread. Its javadoc has a useful example, and its also described in the Swing tutorial.
Multi Threading in java now is very simple with the addition of [java.util.concurrent.][1]
What you need to do is
split the 500 job orders into smaller batches, say 10 per batch.
Create a threadpool with a configured number of threads, say 10 threads.
Create a Runnable/callable task which will pick up these batches from a common place and do the CRUD operations on the DB.
You will additionally need a common data structure which will have the results of these CRUD operations. So once the Runnable/callable task finishes it's operation, it updates this data structure with the result of the operation
Also keep in mind that the access to these data structures
- the one that holds the batch of job orders
- the one that holds the result of operations
should be synchronized.
For thread pool you can use one of the
Executors.newFixedThreadPool or Executors.newCachedThreadPool()
Take a look at Swing Threads.
Especially at:
SwingUtilities.invokeLater()
What you should do is to seperate your UI class from your Database Access and Modifications class. You can then, from your UI you can then call something like this:
new Thread(new Runnable()
{
public void run()
{
//Call database stuff here
}
}).start();
Note however, that having a lot of database operations going on at the same time can cause errors especially since the database might lock tables to which it is currently reading/writing to. What I suggest is that you keep it to one operation at a time and use threads to display a marquee progress bar or something similar.
i'd just use:
new Thread(new Runnable()
{
public void run()
{
//Things to do in new thread...
}
}).start();
Or if you want to use that often, you can make class that implements Runnable, so you dont have to rewrite everything in run() function.