It’s a known fact to every Java developer that not being careful on making use of threads on your application would most probably make it your greatest foe instead of making things better for you. Honestly speaking, I tried to stay away with threads as much as I could. Not because, I am not efficient with it but rather, I am just playing safe when it comes to the problems it might pose on my application, especially in terms of memory leaks.
Sad to say, when you are working with a GUI (Graphical User Interface) based application, it’s less likely that you won’t be using threads. This is due to the reason, that there are a lot of methods that would be best called in the background rather than having the user wait for its completion and make your application hang during this time. One good example would be data population on JTables wherein it won’t really look nice for the user to wait until 500,000 rows of data are retrieved and displayed. Wouldn’t it be nice if things would happen in the background and your application’s UI would still be responsive during this time?
Just recently, I had to work on a Swing/AWT based application and there are some instances wherein I needed to use java threads. Our API makes use of custom Swing/AWT objects and for some reasons, our custom JTextField don’t respond to text input listeners. Instead of trying to change the API, I decided to just think of some workaround so as to prevent introducing new bugs on other components, considering that we are already on a tight deadline for the customer delivery. To make the long story short, I had to create a way in which drop-down menus would be disabled when the user inputs a text inside the TextField and enable the said drop-down menus when no text exists inside the TextField. It’s pretty simple actually, if only our TextField component would listen to text input listeners, but it’s not the case. So what I did was to create a thread that checks the TextField if it contains text or not, and then disable or enable the drop-down menus accordingly. This was the first approach I did:
private boolean monitor = true;
class TextFieldMonitorThread extends Thread {
public void run() {
while (monitor) {
<...do the check here..>
}
}
}
This was obviously an unending loop which I thought woud handle the TextField monitoring well in real-time, but I was wrong. Even though it didn’t pose any memory leaks, it made the CPU usage spike above normal taking around 70% – 80% of the CPU resources.
So what I did was just make use of the TimerThread class so as to make things much easier in terms of CPU usage. This basically creates a background thread that checks the TextField every second.
class TextFieldMonitorTask extends TimerTask {
public void run() {
<... do the check here...>
}
}
TextFieldMonitorTask fmt = new TextFieldMonitorTask();
Timer timer = new Timer();
timer.scheduleAtFixedRate(fmt, 0, 1000);
I’m glad this resolved the problem on CPU usage, even though there might be some slight delay before the drop-down menus were disable or enabled considering the 1 second check interval. Then again this is a pretty good trade off rather than slow down the whole application or even the whole server all together. ![]()
Popularity: 100% [?]
February 25th, 2009 at 2:09 pm
Why are you using a while loop? I think you would be better suited with a for loop. A while loop is only a Boolean test, and it just loops until the condition is true. That could be causing you CPU spike.
February 25th, 2009 at 3:38 pm
Did you Thread.sleep(1000) inside the while loop?
February 25th, 2009 at 4:53 pm
Why was it not possible to use a listener on the textfield? Even if it is custom I see no reason why it shouldn’t support listeners…
Like:
myTextField.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
// text was changed
}
public void removeUpdate(DocumentEvent e) {
// text was deleted
}
public void insertUpdate(DocumentEvent e) {
// text was inserted
}
});
Using a thread just seems like an terrible solution!
February 25th, 2009 at 5:54 pm
cb – I used the while loop to simulate the unending loop, in which truly enough had caused the CPU spike. I’m not sure if for loop would be appropriate here.
Sakuraba – Nope. I didn’t use the Thread.sleep() method inside the while loop.
Mats – I do agree with you that thread is a terrible solution here. Even I don’t feel comfortable with such solution, but I had no choice for such a short deadline and not being allowed to mess up with the core API during those times. There was some issue with the exposure of the JTextField super class from our custom class, which I am now working on, so most probably, I’ll look into your suggestion of using the DocumentLister. Thanks a lot.
Thanks a lot, guys for dropping by and I appreciate your comments and suggestions.
February 25th, 2009 at 6:22 pm
I cringed. DocumentListener on textfield is def way to go. It’s a part of basic swing text components, and Sun even provides it in their swing tutorials
http://java.sun.com/docs/books/tutorial/uiswing/components/generaltext.html
if you can’t change code, then you must have no tests
Rather than thread sleep commands etc. all over the place, a more robust / encapsulated solution would be to use quartz scheduler
February 25th, 2009 at 6:27 pm
javaguy,
As I’ve said, I don’t feel comfortable as well with using threads to accomplish the task. It’s just some sort of short-term workaround for now and I am already doing some code updates to eliminate this unnecessary thread use.
February 25th, 2009 at 10:54 pm
The problem with Swing is that one cannot access a swing object asynchronously because swing has its own thread event loop mechanism and to send an event to a component you have to use those specific sync methods: invokeLater with a Runnable in it.
If I remember, it’s called SwinUtilities.
February 25th, 2009 at 11:47 pm
Threads can be a delicate subject and if they are not handled correctly you may screw your app up. Being ontopic: You could solve the problem by putting a sleep on your thread… What you did there (timer.scheduleAtFixedRate(fmt, 0, 1000); is equivalent with sleep(100)
March 25th, 2009 at 3:03 am
Excellent site http://www.hyperaxe.com and I am really pleased to see you have what I am actually looking for here and this this post is exactly what I am interested in. It’s taken me literally 3 hours and 10 minutes of searching the web to find you (just kidding!) so I shall be pleased to become a regular visitor
April 24th, 2009 at 7:26 pm
I’m the only one in this world. Can please someone join me in this life? Or maybe death…
July 14th, 2009 at 9:58 pm
Hello everyone
I just wanted to make a statement on the contribution of this community here. It’s amazing.
I want to contribute my part to this forum as well
There is a site that has been awfully helpful to myself and some associates of mine. That site is OnlineComputerHelpers.com and they offer remote pc http://www.onlinecomputerhelpers.com – computer repair
I hope that my aid has been substantial and you also are able to use their services just as I have.
August 1st, 2009 at 7:06 pm
Sandra Dalene VanAlstine – Wanted to introduce myself
Thanks
Sandra Dalene VanAlstine