2000-11-30 The Java™ Specialists' Newsletter [Issue 001] - Deadlocks

Author: Dr. Heinz M. Kabutz

(C)opyright Maximum Solutions, South Africa

If you are not already subscribed to this newsletter, you can either subscribe via email or subscribe via the web. Be warned that if you are a beginner in Java, you will at times struggle to keep up.

Welcome to "The Java™ 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™ 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.

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.

With regards

Heinz


(C)opyright Maximum Solutions, South Africa

The Fine Print
Mission. This newsletter began at the end of 2000 with about 150 readers that I had gleaned from my contacts list. Since then, it has grown to its current readership exceeded 1'000 readers, necessitating a move to a "proper" mailing system. It's goal is to share some advanced ideas and thoughts on Java programming and the way that a Java specialist would deal with problems "in the field". Carl Smotricz is currently hosting an archive of past newsletters.
Reprint Rights. Copyright subsists in all the material included in this email, but you may freely share the entire email with anyone you feel may be interested, and you may reprint excerpts both online and offline provided that you acknowledge the source as follows: This material from The Java(tm) Specialists' Newsletter by Maximum Solutions (South Africa) - The Java(tm) Specialists. Please contact Dr. Heinz M. Kabutz (h.kabutz@computer.org) for more information.


Please contact me if you would like to put a link to this newsletter on your website.