Skip to main content

Debugging Swing, the summary #1

Posted by alexfromsun on January 12, 2006 at 9:38 AM PST

Well, I've got more than 30 comments for the previous blog.

It's high time to summarize them and make up a conclusion.

There are two separate enhancements were suggested in comments:

  1. Make compiler move Swing methods to EDT automatically
  2. Invent something to make finding out-of-EDT methods invocations easier

Making Swing methods threadsafe, simple case

Really, if you call Swing method out from EDT why compiler can't move it to EDT automatically ?

For example we can mark necessary methods with @OnEdt annotaions and...
what's next ?

The compiler could probably insert SwingUtilities.invokeLater automatically:


        public void removeAll() {
               // implementation skipped...


        public void removeAll() {
            if (!SwingUtilities.isEventDispatchThread()) {
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {                    
                // implementation skipped...

No need to write InvokeLater(..) yourself anymore, compiler is doing it for us.

Sounds good, but let's think about implementation of this feature.

One of the serious drawback of such solution is a performance:

You'll need an additional inner class for each @OnEdt method,
it will make Swing bigger and slower

The second problem is not so visible,
because this approach works relatively good for simple methods without parameters and return type only

Making Swing methods threadsafe, real case

consider the more usual case:

        public Component getComponent(int number) {
             // implementation skipped... 
            return aComponent;

This method takes a parameter and returns a value,
so to make this method thread safe we need:

  1. turn parameter into final int constant to be accessed in the inner class
  2. block the thread and wait for the result,
    so invokeLater() is not good here
  3. it becomes more tricky if methods throws checked exceptions,
    in this case we need to catch them in the inner class and rethrow them properly

The guru of Swing threading and one of the creators of SwingWorker,
Igor Kushnirskiy offers the following scheme to convert the body of EventDispatchThread only method to a thread safe one

        if (!SwingUtilities.isEventDispatchThread()) {
            store all the method arguments in final variables
            Callable callable =
                new Callable() {
                    public T call() throws Exception {
                        return invoke this method;
            RunnableFuture future = new FutureTask(callable);
            try {
                return future.get();
            } catch (InterruptedException e) {
                //unlikely to happen
              throw new RuntimeException(e);
            } catch (ExecutionException e) {
                //rethrow all exceptions properly
                Throwable cause = e.getCause();
                if (cause instanceof RuntimeException) {
                    throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
                    throw (Error) cause;
                } else if(cause instaceof one the checked exceptions of the method) {
                    throw (this exception)cause;
                } else {
                    throw new RuntimeException(cause);
         } else {
             return invoke original method body;

To block the thread during return value calculation
class is used instead of invokeAndWait() but this choice mostly is a matter of style.

Looks much more scary, doesn't it ?


Standard Java doesn't support preprocessors or any other way to insert an additional code into existing method and there are some strong reasons why is it so.

Peter van der Ahe, a java compiler expert expains it in very clear way:
"One of the strong principles of Java is that what you see is what you get. There is nothing fancy going on behind the scenes. Based on this principle, Java doesn't support macros or AOP."

If we generate a bunch of additional code for methods marked with @OnEdt annotation we would compromise this principle.

If java invoked methods on the other thread behind the scene
it might cause difficult to find deadlocks, because it would be not trivial task to underestand threading relations

"What you see is what you get" - the code is 100% controlled by a programmer, no tricky magic, everything is clear

Hence thinking about all listed problems
automatic EDT dispatching doesn't look as good now as it used to.

Check out a good Graham Hamilton's blog about "a multithreaded toolkit dream".

It is becoming clear why SWT, Win32 API, Motif, Xlib and GTK
are not thread-safe libraries as well.

Improving Swing debugging is much more realistic and promising issue,
I'll cover it in the next blog.

Stay tuned !

Related Topics >>