Technologies Used:
Java 1.6
SWT GUI
Problem:
GUI information updates eventually stall (GUI becomes completely unresponsive) after approximately 60 minutes of a background task running.
The problem appears to be with the GUI updates, and I cannot figure out how to remedy this situation (reviewed the Java concurrency options, etc.). The Optimization thread periodically updates the text box in the GUI with processing information. During my testing, this "update" lags SIGNIFICANTLY behind the console output and database output--by that, assume the optimization performs 4000 optimization steps. The console may report working on optimization step 1900 (confirmed in the database) but the GUI stills outputs information from step 700.
Background Info:
I am running a machine learning optimization task and incorporate the task into an SWT GUI. The task may take an hour or more to run to completion depending on parameters. I designed the optimization task as a separate thread. The GUI allows the user to press a button to launch the optimization. The GUI includes (to simplify) 1) a table of tasks and 2) a SWT text box for feedback during the optimization. The table of tasks gets updated as each distinct task group is completed. The SWT text box outputs more regular/frequent feedback (much like System.out BUT using threading to update the text box via the GUI EDI thread). That is, I believe I am using at least three threads: 1) the GUI thread, 2) the aSync thread for GUI updates (SWT), and 3) a background thread for the optimization itself. (I mention this because the Java concurrency tutorials expressly direct that long running tasks must run in their own thread to avoid GUI deadlock and starvation. However, even though I think I did this, the GUI still stalls after a long optimization run--and this is what I am trying to fix. Because the optimization runs take so long to complete, the GUI stall is a major issue--losing more than an hour before realizing the GUI stalled.)
Basic Program Structure:
GUI Class-->launches a separate thread for the Optimization Class
Optimization Class can update GUI class components (using SWT asyncExec) via call-backs
Confirmed:
I can confirm that the background thread runs fully--1) the background thread updates several database tables and all tables are fully and completely updated; 2) System.out output directly from the optimization task sent to console in Eclipse shows the optimization thread runs fully and completely.
Furthermore, during testing, if I scale back the optimization set to perhaps 400 steps, the GUI seems to run fine.
Relevant Code:
GUI CLASS--
Code to Update GUI and in GUI Class (this gets called by the Optimization Class Thread)--
public void setFeedback(final String workerthreadinfo, final boolean append) {
try{
Display.getDefault().asyncExec(new Runnable(){
public void run(){
if(!textfeedback.isDisposed() && textfeedback !=null){
if (append) {
textfeedback.setText(workerthreadinfo + "\n" +
textfeedback.getText()) ;
} else {
textfeedback.setText(workerthreadinfo) ;
}
}
}
});
} .....
Instantiation of the Optimization Worker Thread in GUI Class
private OptimizerWorkerThread workerthread =
new OptimizerWorkerThread(this) ;
Code in GUI Class Launching the Optimization Class (as thread)
protected void optimize() {
workerthread.go() ;
}
OPTIMIZATION CLASS--
Optimization Thread Method "linking" to the GUI (guiwindow = GUI class above)
// ==================================================================
// GUI Update Methods
// ==================================================================
public void updateFeedBackInfo(String update, boolean append) {
guiwindow.setFeedback(update, append) ;
}
Example of Call Back to GUI from the Optimization Thread
//GUI Feedback
this.updateFeedBackInfo("Saving optimization run record to database ... ",
APPENDTEXT ) ; // APPENDTEXT = boolean TRUE instructing GUI textbox to append
This does not sound so much like a threading issue.
If you would run by accident in the GUI thread, the GUI would be dead right after clicking the button. So I think we can rule that out.
What you describe sounds more like a memory load / performance issue. I strongly recommend connecting Visualvm with your application and look especially for constantly increasing memory consumption. Also using the profiler included in visualvm might hint at stuff that is consuming lots of cpu or memory.
Solution Addendum:
During final testing of this application, I more carefully identified the apparent source of the GUI slow down. By GUI slow-down, I mean the difference between copying 2500 files. The slow-down problem required almost 20 minutes to complete the copy. With the fix applied, the exact same files took less than 1 minute to copy.
The Problem
The copy is handled through a Worker Thread. The worker thread periodically updates the GUI. The update includes a ProgressBar update and a text box update.
The text box update appears to be the source of the problem. What I wanted was a text box the PREPENDS the status update information--such as "Copying File C:/hello.txt"--rather than append (available in SWT). To create a faux prepend I used (in a separate thread):
textfeedback.setText(workerthreadinfo + "\n" + textfeedback.getText()) ;
This little piece of code appears to be the slow-down culprit--and probably is easy to see why. On every file copy, the entire text box contents are copied then the new information is prepended to the text box. After copying about 700 files, this starts to bog down (you can see the slow-down visibly) and continues to deteriorate afterwards.
The fix, although I am not happy with it, is to use the SWT TextBox append() method instead.
Related
I have my JavaFx application that reads data from API on background thread ( or for testing it is preloaded from local storage on application start ) and then it processes and sets data to model that is directly binded on properties in my view. Because processing and setting data to model changes text shown in components, it is called with Platform.runLater(). Normally when it is called it consumes around 2% of CPU, but if i run application for longer time, consumption of CPU on data processing goes higher a little bit(probably data processing is too much for GUI thread). It gets for example around +4% in 1 hour.
However what I see as strange behaviour is that when i lock my Windows and go away for few minutes and then come back, CPU usage on data processing changes from 8% to 17% for example and then stays that high. Does it mean that when Windows screen is locked then GUI thread doesn't run? It seems to me like not and then when it unlocks, GUI thread gets overwhelmed byPlatform.runLater() calls. But when it is not processing data, it consumes 0% of CPU, so i'm really confused.
Does anyone know what could cause this? Does GUI thread really stops working when windows are locked?
EDIT:
I've already found that processing received data is probably too intensive task for UI thread and I'm trying to optimize it (do most of processing on background thread and then just call setting data with Platform.runLater.
Code for background download is really simple PoF at this moment and looks like this:
Thread updateDaemon = new Thread(() -> {
try {
while (true) {
TimeUnit.SECONDS.sleep(5);
processMarketStateData(view.getTable(), data);
}
}
}
catch (InterruptedException e) {
logger.error("Background worker interrupted", e);
}
});
updateDaemon.setDaemon(true);
updateDaemon.start();
In processMarketStateData i do some processing and then set data to model on UI thread. But what i'm actually curious about is that strange CPU usage behaviour. When update thread is sleeping and i do not interact with UI then CPU usage is 0%. When processMarketStateData it takes few % of CPU and then it is again 0% till update thread ends its sleep. But for some strange reason after several processMarketStateData calls CPU usage goes up more and more. I goes up by small percentage, like 1% after 50 calls, maybe more. Even weirder is it takes way less calls to produce this strange behaviour when windows screen is locked. When it goes really insane and it takes already around 20% of CPU for call, it goes that high only on processMarketStateData call, for rest of the time it is 0%. After really long ( few hours ) test i ended up in state where application took 25% of CPU permanently and UI was inresponsive. Note that there are 2 these threads running at same time.
My actual question is not "why my ui lags when i process data", that was not hard to find, but it is "why it acts the way it does?"
I hope this edit made my question better.
EDIT2: Another strange behaviour as well is that if I leave application minimalized for a while with auto updating and open it then, it is black window for a while, but application that doesn't have auto update is ok. This really makes me think that javaFX UI thread doesn't run when application is minimalized or windows screen is locked. Sadly i could not find much about this.
probly these links may help you
Execute task in background in JavaFX
https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm
https://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm
This may be you are doing a cpu intensive task in UI thread . please provide some code samples.
you can use a service class to do the cpu intensive calculation and then update the ui in the plateform.runlater call.
It seems that I've found the real issue and fixed it. Unfortunately unless I would share my whole project, you would not be able to help me. Problem was that there was method called from processMarketStateData method that sets style depending on data received. Problem was that it called node.getStyleClass().add(style) without checking presence of style. So after 15 minutes size of node.getStyleClass() was around 300. After adding that check it seems that everything runs ok and it takes max 2% of CPU.
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.
Good day, I want to make in java swing opening tabs in new threads and it would have had the opportunity to run time-consuming tasks to switch between tabs. Tried it, a copy of the tab implement the interface Runnable, but a new thread is not valid (in the debugger it starts hanging about 1 sec, and is killed), as I understand the constructor work out, and all the contents of the swing is placed in its major flows. I read about SwingWorker, but do not quite understand how you can apply it to my problem. If you can, please show an example. Thanks in advance.
P.S. This is network application, and "load" will serve as a work with the server. That is, in other words, to give the user the ability to switch between tabs until the current tab is a connection.
You should try to separate the code that does the actual work from code that specifies the GUI. You should search e.g. for the Model-View-Controller-Pattern (MVC).
This way the GUI code can run inside the event-dispatcher-thread (EDT) of Swing / AWT how it is more or less inteded. The code that does the actual work should be as independent from the GUI as possible. Now you can choose to run it in a dedicated thread or whatever fits best into you overall application architecture.
The last part is wire these two (the GUI and the domain logic) together, so that the GUI triggers the worker code or the worker code triggers GUI updates, or whatever satisfies the workflow requirements.
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.
I'm writing a little genetic algorithm in Java, as a school assignment. Up until now I've pretty much stuck to doing console applications. However I think a UI would be really helpful for this program, so I'd like to make one. I'm having trouble figuring out how to reconcile a GUI which is event-driven, and a console application which has a beginning and end.
Ideally I'd like to have a bunch of text boxes for settings, and then a Start button. Once you hit Start, the algorithm would start running and the GUI would update on a set interval with the latest program state. How the heck do I accomplish this without the algorithm freezing the GUI or vice-versa? I don't want either one waiting on the other.
How do I get my main loop to not freeze the GUI while the algorithm is running? I assume they need to be in separate threads, but I've never messed with threads before. That seems too complex for this task, which must be commonplace.
You're on to something with threads. GUI programming mandates threads, in most cases -- luckily, Java's threading API isn't too terrible (Python's is modeled on it, so it's doing something right).
Don't be intimidated by threading, though -- it's intermediate, I'd say, but is something that every programmer should understand.
There's a lot of information out there that would predispose you against threads. GUI applications, however, are one area where they are phenomenally useful. Opponents of threading would lead you to believe that an event-programming model would help you in this case, when really, it will not. The solutions that most who say "threading sucks" propose are often worse than threading itself.
You could try to kludge your solution into a single thread, but it would require your CPU-intensive code to yield to the GUI at a predictable interval. That solution sucks. EDIT: Since others are suggesting that approach, let me elaborate on why it sucks: Unbeknownst to you, something is always being updated in a GUI. When you move a window on top and then back off, the entire region under that window is invalidated and code must execute -- in your process -- to redraw that section. Even if you are updating the GUI very quickly, this provides a negative user experience as simple GUI operations block entirely. Buttons highlight when you mouse over, sometimes. A user right clicks. All of these things require CPU time to implement, and if your solitary thread is chewing away on your GA, they will not happen. GUI code being executed is not only your code.
Here's what appears to be a very useful article on the topic.
Two lessons in the trail on the topic are:
Concurrency
Concurrency in Swing
Sorry - it would seem like background tasks would be an easy and obvious sort of thing. Unfortunately, the Java Swing GUI threading model is a bit complicated. There have been some improvements in this area, but one still has to have some knowledge of threading first.
If you have time, I'd suggest reading the chapter on threading in Filthy Rich Clients - Painless Threading through SwingWorker.
If your impatient, just read the JavaDoc on SwingWorker. If you're really impatient, just copy the meaning of life example from the JavaDoc sample usage.
When I was writing a ray-tracer for one of my computer graphics classes in college, I had a long-running task, and I wanted to update the display periodically as the tracer was drawing. I used two separate threads - one thread sleeps, and updates (say every 500 ms); the other thread does the actual raytracing. The key is to synchronize on a common object - in my case, accessing my image buffer was the point of synchronization (one thread can't make changes to the image buffer without first waiting until the other thread is done reading).
For your GA processing, you might have something like this (pseudocode):
Supposing you have some object, generationHistoryObject, which stores the state that you want to display in your GUI, then:
(in Thread #1:)
Generation newGeneration = doMutationAndTestThisGeneration(lastGeneration);
synchronized (generationHistoryObject) {
generationHistoryObject.updateWithNextGeneration(newGeneration);
}
(in Thread #2:)
while (!programIsDone()) {
synchronized (generationHistoryObject) {
drawGuiForCurrentState(generationHistoryObject);
}
Thread.sleep(500);
}
The idea is that you do the time-consuming work for each generation in isolation, then update the part that the GUI has to access in the synchronized block (making the GUI wait to draw until the update is done).
Your problem with Swing is that it is single threaded (which is a good thing) so you want to get your work out of the Swing thread so your application stays responsive.
The thing you need to do is to convert your core algorithm to a Runnable as it can be handled easily by a SwingWorker and with the newer Executors (see Executors for a lot of preconfigured ones). You can also create investigate how to make a PrintStream to a JTextPanel so you can just use standard println statements to output your current status information.
If you want to add a stop button you need to understand the thread model, so you know how to control it. The Java Tutorial has good material on this as well as Swing programming in general. Strongly recommended.
http://java.sun.com/docs/books/tutorial/uiswing/concurrency/index.html
Since your application has to do with genetic algorithms, you could update the GUI every generation or so. You could accomplish this by implementing a next() method in your algorithm code, and calling it from the GUI. This should be simple enough.
However, if you really don't want the GUI to freeze while waiting for the algorithm, you should go for threads.