I'm writing a java application that encrypts and decrypts the input by DES algorithm. First I made it without GUI and printed the intermediate steps in the output window by using System.out.print();. When the input is large, the calculations can take a while but when using the output window the intermediate steps where printed one by one while it was calculating. That was perfect.
Now I made a GUI for my program, using a JTextArea, called txtDebug for printing the intermediate steps:
public static void debug(String tekst){
txtDebug.setText(txtDebug.getText()+tekst+"\n");}
The problem: the intermediate steps aren't printed one by one anymore. If the input is large, the program just freezes and does nothing, until the calculations are all done, and then it prints the intermediate steps all at once.
Another problem: when I wasn't using the GUI, the program never crashed, now if the input is large enough, the program crashes: it freezes and just never comes back to life.
Any help please?
You must do the work in a background worker thread. Doing it in the main thread will prevent Swing from processing events -> the UI will block.
http://www.kdgregory.com/index.php?page=swing.async
http://download.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html
The user interface is freezing because you're performing long running calculations on the Event Dispatch Thread, the thread responsible for processing events and repainting the UI. To avoid this problem consider performing the encryption / decryption on a background thread, perhaps using a SwingWorker.
Regarding the second point about the user interface never coming back to life this could indicate another resource problem (e.g. memory). You might want to run a profiler or JConsole to see the state of each thread when this problem occurs.
Related
I am creating a live graphing application, using a library called 'LiveGraph', which I stumbled upon. Essentially, the LiveGraph application is a GUI that keeps on reading from a text file with data, and updates the corresponding graph.
Here is a snippet of the code I have (explanations below:
for (VisualDisplay vd : visDisplayElements) {
vd.display();
System.out.println("Done executing.");
}
while (!dcm.done) {
String packet = dcm.run();
HashMap<String, Integer> dataMap = initializeMap (packet, config.delimiter, config.colNames);
for (VisualDisplay element : visDisplayElements) {
element.receivedDataSet(dataMap);
}
}
The first for loop essentially goes through the list of graphs and loads up the GUI for each of them. The while loop afterwards essentially keeps polling forever for data through the network.
Now here's the scenario: When I am only displaying the graphs (i.e., if I comment out the while loop), the graphs display and open up (but obviously don't display anything because nothing is polling). However, with all the code as shown below, the GUI windows for the graphs open up, but turn out completely gray, with no content. If I try resizing or interacting with them in any way, the application freezes, and I have to force quit.
I'm narrowed this down to the issue that threading is somehow a problem here. The while-loop will keep running forever, and maybe the GUI's will not run properly due to that. I am looking for a solution to this, that maybe involves threading. I'm tried a few basic things, such as running the display and polling each as separate threads, but I was getting nowhere.
I read about threads in Android Studio and I wanted to ask some questions. Are threads a must have in my application to avoid lag or only when you make really big and consuming apps? I am asking this because I have little lag on my app and I wanted to know if it is because I didn't use threads. I don't think it is because of useless stuff I did, I was pretty vigilant with that.
Threads are a vital component of building any large scale application. For example lets say you have a line of code that performs some unit of work which requires some time to be finished for example
...
// takes 500ms to complete could be a network operation/could be accessing camera,
// initializing recorder etc. (Initalizing recorder takes 100ms most of the time)
doSomeTimeIntensiveTask();
...
In such cases you would need to perform this task on a different thread and not on your UI/MAIN thread because for a end user using the application, IF you were to perform this on the UI/MAIN thread then he/she would notice the time delay as a stutter/lag kind of experience which makes for a bad UI experience in general.
Additionally there are tasks like making a HTTP request that require an in-determinate amount of time to actually finish in such cases, if such tasks was performed on the UI/MAIN thread then the application would be STUCK until the task was completed which sometimes causes the android OS to show pop up messages like the application doesn't seem to be responding do you want to force close the app? or some similar message, which again is bad user experience.
So in your case, I would try to identify exactly which piece of code is causing the lag in my UI/MAIN thread and put that part of the code in a separate thread and write a callback to continue executing correctly.
Without more information, it is impossible for anyone to answer this question in any reasonable manner.
Generally speaking, though, the main reasons to create additional threads (beyond the ones already used in the framework), is if you are doing heavy operations such as I/O (heavy read/write or http), graphics, or really complex calculations.
Look into Processes and Threads and AsyncTask.
To briefly quote the most relevant portion to this question:
When your app performs intensive work in response to user interaction, this single thread model can yield poor performance unless you implement your application properly. Specifically, if everything is happening in the UI thread, performing long operations such as network access or database queries will block the whole UI. When the thread is blocked, no events can be dispatched, including drawing events. From the user's perspective, the application appears to hang. Even worse, if the UI thread is blocked for more than a few seconds (about 5 seconds currently) the user is presented with the infamous "application not responding" (ANR) dialog. The user might then decide to quit your application and uninstall it if they are unhappy.
I'm fairly new to java and I was creating a program which would run indefinitely. Currently, the way I have the program set up is calling a certain method which would perform a task then call another method in the same class, this method would perform a task then call the initial method. This process would repeat indefinitely until I stop the compiler.
My problem is when I try to create a GUI to make my program more user friendly, once I press the initial start button this infinite loop will not allow me to perform any other actions -- including stopping the program.
There has to be another way to do this?
I apologize if this method is extremely sloppy, I sort of taught myself java from videos and looking at other programs and don't entirely understand it yet.
You'll need to run your task in a new thread, and have your GUI stuff in another thread.
Actually, if you keep working on this problem, you'll eventually invent event driven programming. Lots of GUI based software, like Android, use this paradigm.
There are several solutions. The first that comes to mind is that you could put whatever method needs to run forever in its own thread, and have a different thread listen for user input. This might introduce difficulties in getting the threads to interact with each other, but it would allow you to do this.
Alternatively, add a method that checks for user input and handles it inside the infinite loop of your program. something like below
while(true){
//do stuff
checkForUserInput();
//do other stuff
}
To solve this problem, you need to run your UI in another thread.
Many programs are based on an infinite loop (servers that keep waiting for a new user to connect for example) and your problem isn't there.
Managing the CPU time (or the core) allocated to your infinite loop and the one allocated to take care of your UI interactions is the job of the operating system, not yours : that's why your UI should run in a separate thread than your actual code.
Depending on the GUI library (Swing, ...) you're using there may be different ways to do it and the way to implement it is well answered on Stack Overflow
I have a SWING UI that contains a button that creates a new SwingWorker thread. That thread then queries the SQLite database for results to put them in a JTable. In my StringWorker constructor, the parameters are various fields taken from other SWING components such as a JSpinner, JComboBoxes, etc.
Since I'm new to all of this thread thing, I'd like some advice from more knowledgeable programmers on how I should go about doing what I want to do.
I'd like to know if threads automatically end when I close the program with System.exit(0); so I don't end up with memory leaks
What is the best way to make sure I don't have two threads accessing my database at the same time (let's say the user clicks multiple times on the button or, other case, an administrator is updating the database with some files as input (within my program), then while the first thread is parsing the files and updating the database, he wants to query the database using the button, etc.).
Is it slower to use threads? At first I did all my calculations right in the EDT and of course the UI locked every time after pressing the button, but it only locked for about 5 seconds if I recall correctly. Now, when I press the button, it doesn't lock up but it seems like the result take about a little bit less than twice as long to show up in the JTable. Is it because I made a mistake in my code or is this normal?
I though about using a static field in the class the queries are in and setting it to true if it's in use. Is that the correct way of doing it? That way, not matter which thread is using the database, the second thread won't launch.
If it's not absolutely necessary (it shouldn't be), don't use System#exit in your code. Here are some explanations why and what is better.
Your database is capable of handling two concurrent requests, so it's not a bad thing in itself. If you use JDBC and its pooled connections via DataSource, then you should probably restrict the usage of one such a connection to one thread at a time. To cure the problem of having redundant database queries, e.g. when "clicking twice", there is probably more than one solution. I assume here that you mean the scenario where you have a Swing UI that is distributed to several people, and each of these instances talks to the same database -> simply disable your button as long as the execution of the database query takes.
It's slightly slower if you do not run your code directly in the Event Dispatch Thread due to scheduling of execution of your workers, but this should not be noticable. To see what goes wrong I would have to see the relevant code.
I'd like to know if threads automatically end when I close the program with System.exit(0);
Yes. Entire process will end and threads that are part of this process. However, if you don't call System.exit(), all non daemon threads must finish before process is gone.
What is the best way to make sure I don't have two threads accessing my database at the same time
Since it's a Swing application, I assume that both you and administrator can't access the application at the same time. However, to guarantee that even in single application you can't start more than one operation affecting database, you have to block UI. Either disable buttons or put glass pane on top of UI. Modal progress dialog is also helpful.
Is it slower to use threads?
No, it is not slower if done right. Slow operation will take as long as it takes. You can't fix it with threads, but you can, either keep speed (perceived) the same while providing nice, non blocking UI or you can do more than one slow operation at a time and therefore increase that perceived speed.
I'm new to advanced programming - but from what I've read, all my android programs are on one thread.
This means, only one line of code or method/function can be executed at a time before moving on to the next line (that's what I thought anyway).
However, I'm using a custom dialog to develop this application and yet, the program continues even after the dialog has ran. I'd like my program to wait for the dialog to close so that I can receive the input and manipulate it.
This seems fairly straightforward when programming in Java (e.g. the Scanner tool waits for the user input before proceeding as opposed to running the code following it while it waits for user input).
How can I do this?
Everything does happen on one thread unless you explicitly tell it not to. However, showing a Dialog happens asynchronously. Basically, when you ask the Dialog to show, it adds that information to a list of UI events that are waiting to happen, and it will happen at a later time.
This has the effect that the code after asking the Dialog to show will execute right away.
To have something execute after a Dialog choice is made, add an onDismissListener to the dialog and do whatever it is you want to do in onDismiss.