|
The Java Specialists' Newsletter
Issue 001 2000-11-30
Category:
Performance
Java version: Deadlocksby Dr. Heinz M. Kabutz
Welcome to "The Java(tm) Specialists' Newsletter", a low-volume newsletter exploring
experiences of using Java "in the field" (not only
java.lang.reflect.Field, but that also). The reason I have sent this email to
you is because you were either on a Java course presented by me, or you are a
colleague, or I thought the topic might simply interest you.
Just to clear things up, as I always tell my students, my company's name is Maximum Solutions
and our logo is "The Java(tm) Specialists", hence the title for the
newsletter. This does not mean we are good at Java, it simply means that this
is all we do (at the moment). Perhaps in future I will change my logo to "The
XML Specialists", or, heaven forbid "The VB Specialists", but
then I would have to be really hard-up ;-) The logo is therefore not a display
of my arrogance (those of you who know me better would assure you that
arrogance is definitely not one of my characteristics, neither is a bad haircut
nor rolled up jeans) but is supposed to give me focus in the IT industry.
A warning I feel I have to give you is that the tricks I have discovered in Java are not always
"kosher" and are used solely at your own risk. Whenever I mention
something that is non-kosher I will also attach a warning label so the more
experienced of you can use it and the rest not. Always make sure that your unit
tests run before and after a change to a new JDK version, the days of JDK 1.1.x
were extremely interesting because each version screwed up the South Africa
Locale in a different way. For the past
3.5 years I've been programming exclusively in Java and I can say that it is a
fascinating language. Once you dig
below the surface of Java it becomes increasingly more fun and interesting to
work with, and you end up wanting to exploit the limits of the JDK (last week I
made a piece of code I had written with someone else 2 years ago 1000x faster).
The JDK 1.3.0 source code contained in the
src.jar file when you install the JDK contains a lot of Java code, 574253 lines
of Java code to be exact, which is slightly less than the Java program written
in Stellenbosch in South Africa where I gained most of my Java programming
experience.
Thanks for reading this newsletter on our website. We also have a mailing list. That is where the real action takes place (webinars, free reports, etc.). Maybe subscribe today?
Advanced Java Courses on Crete:Java Specialists Master Course 18-21 June 2013 and
Concurrency Specialists Course 6-9 August 2013.
Deadlocks in Java
While travelling overseas I had the priviledge of spending
some time helping a Java program in dire straits. It was a
graphical interface that was supposed to emulate a C++ program
running on a server, bla bla bla. Anyway, this application
would occasionaly have a thread deadlock with the result that the
screen would stop refreshing. Imagine the despair when facing an
unfamiliar source base of several 10'000 lines of Java code with
a deadlock SOMEWHERE in there?!? The code was well written, but
even though, the task was scary. Luckily I had heard somewhere
about the secret CTRL+BREAK trick that SUN smuggled into the JDK
without telling anybody. If you press CTRL+BREAK while your
Java program is running in a command prompt you get a stack
trace of exactly what each thread is doing and by looking at
the code you easily find which thread is waiting for which lock!
When you get a deadlock in your program you want to be able to
reproduce it reliably as quickly as possible, so we got half
the team to just concentrate on finding deadlocks that they
could reproduce. In the meantime, the other half would look at
the stack traces and figure out why the code was deadlocking.
In the process of looking we discovered something which I
had heard about second-hand but had not encountered myself.
Last week I heard of the same problem occuring at another company
which took a lot of effort to clear up, so if your program has
any GUI in it, especially Swing, it might pay to listen to this:
In Swing, all GUI components have to be changed from within
the Swing thread.
This means that you cannot execute jLabel1.setText("blabla")
from within any thread besides the Swing thread.
If you have change any GUI from another thread you should
rather say:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
jLabel1.setText("blabla");
}
}
This will do the change that you requested as soon as it can,
which is usually within a few microseconds. There is another
call invokeAndWait which I have hardly ever used except in
race-conditions.
I was under the impression that failure to use invokeLater
would cause some refresh problems of a kind where some parts of
the screen get refreshed and others not, I did not realise it
could cause a thread deadlock (or maybe that is what everyone
was talking about - refresh problem - hmpf - more like a system
meltdown). Luckily you don't always have to call invokeLater
whenever you change a GUI component because in some cases you
already are in the Swing GUI thread, for example if a button is
pressed then the ActionListener.actionPerformed method will be
called from the Swing thread. However, if you provide a callback
class to another class that is not part of the AWT/Swing group
you will never know what thread it is coming from, so it is
safest to invokeLater.
Remember that any work you do in invokeLater is going to hold
up the Swing thread from repainting the window, so please don't
do big database queries inside invokeLater but rather only call
invokeLater for the parts of the code that are genuinely graphics
related. It might pay off to bunch all the GUI related lines
in your method by refactoring your code a bit. For information
on refactoring look at the book with that title by Martin Fowler.
---
Warning Advanced:
A small optimisation is to have a class that
figures out if the current thread is the Swing thread
(SwingUtilities.isEventDispatchThread()) and if it is not calls
SwingUtilities.invokeLater(Runnable), otherwise it calls the
runnable code directly. This way you can finish everything you
need to do without interference by other threads. Reason for
the Non-Kosher label is that it seems you can have several event
dispatch threads, I don't know under what circumstances so if
you know, please enlighten me. However, it almost seems like
only one of them can be active at any one time.
---
Anyway, this is the end of the newsletter for tonight, so please
let me know your comments and feedback and remember to please
let me know if I'm wasting your time with this stuff then I'll
not send any more to you.
Kind regards
Heinz
Performance Articles
Related Java Course
Discuss at The Java Specialist Club
|